locking/lockdep: Fix debug_locks off performance problem
Sasha Levin
maintainerPATCH 1/22 locking/lockdep: Fix debug_locks off performance problem
From: Waiman Long <[email protected]>
[ Upstream commit 9506a7425b094d2f1d9c877ed5a78f416669269b ]
It was found that when debug_locks was turned off because of a problem found by the lockdep code, the system performance could drop quite significantly when the lock_stat code was also configured into the kernel. For instance, parallel kernel build time on a 4-socket x86-64 server nearly doubled.
Further analysis into the cause of the slowdown traced back to the frequent call to debug_locks_off() from the __lock_acquired() function probably due to some inconsistent lockdep states with debug_locks off. The debug_locks_off() function did an unconditional atomic xchg to write a 0 value into debug_locks which had already been set to 0. This led to severe cacheline contention in the cacheline that held debug_locks. As debug_locks is being referenced in quite a few different places in the kernel, this greatly slow down the system performance.
To prevent that trashing of debug_locks cacheline, lock_acquired() and lock_contended() now checks the state of debug_locks before proceeding. The debug_locks_off() function is also modified to check debug_locks before calling __debug_locks_off().
--- kernel/locking/lockdep.c | 4 ++-- lib/debug_locks.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
kernel/locking/lockdep.c +2 -2
@@ -3808,7 +3808,7 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip) {unsigned long flags; -if (unlikely (!lock_stat)) +if (unlikely (!lock_stat || !debug_locks))return ;if (unlikely (current->lockdep_recursion))
@@ -3828,7 +3828,7 @@ void lock_acquired(struct lockdep_map *lock, unsigned long ip) {unsigned long flags; -if (unlikely (!lock_stat)) +if (unlikely (!lock_stat || !debug_locks))return ;if (unlikely (current->lockdep_recursion))
lib/debug_locks.c +1 -1
@@ -37,7 +37,7 @@ EXPORT_SYMBOL_GPL(debug_locks_silent);*/ int debug_locks_off (void ) { -if (__debug_locks_off ()) { +if (debug_locks &&__debug_locks_off ()) {if (!debug_locks_silent) {console_verbose ();return 1 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 2/22 ataflop: fix error handling during setup
From: Omar Sandoval <[email protected]>
[ Upstream commit 71327f547ee3a46ec5c39fdbbd268401b2578d0e ]
Move queue allocation next to disk allocation to fix a couple of issues:
- If add_disk() hasn't been called, we should clear disk->queue before calling put_disk().
- If we fail to allocate a request queue, we still need to put all of the disks, not just the ones that we allocated queues for.
--- drivers/block/ataflop.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
drivers/block/ataflop.c +15 -10
@@ -1933,6 +1933,11 @@ static int __init atari_floppy_init (void) unit[i].disk =alloc_disk (1 );if (!unit[i].disk) goto Enomem; + + unit[i].disk->queue =blk_init_queue (do_fd_request, + &ataflop_lock); +if (!unit[i].disk->queue) + goto Enomem; }if (UseTrackbuffer <0 )
@@ -1964,10 +1969,6 @@ static int __init atari_floppy_init (void)sprintf (unit[i].disk->disk_name,"fd%d" , i); unit[i].disk->fops = &floppy_fops; unit[i].disk->private_data = &unit[i]; - unit[i].disk->queue =blk_init_queue (do_fd_request, - &ataflop_lock); -if (!unit[i].disk->queue) - goto Enomem;set_capacity (unit[i].disk,MAX_DISK_SIZE *2 );add_disk (unit[i].disk); }
@@ -1982,13 +1983,17 @@ static int __init atari_floppy_init (void)return 0 ; Enomem: -while (i--) { -struct request_queue *q = unit[i].disk->queue; +do { +struct gendisk *disk = unit[i].disk; -put_disk (unit[i].disk); -if (q) -blk_cleanup_queue (q); - } +if (disk) { +if (disk->queue) { +blk_cleanup_queue (disk->queue); + disk->queue =NULL ; + } +put_disk (unit[i].disk); + } + }while (i--);unregister_blkdev (FLOPPY_MAJOR ,"fd" );return -ENOMEM ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 3/22 swim: fix cleanup on setup error
In reply to Sasha LevinFrom: Omar Sandoval <[email protected]>
[ Upstream commit 1448a2a5360ae06f25e2edc61ae070dff5c0beb4 ]
If we fail to allocate the request queue for a disk, we still need to free that disk, not just the previous ones. Additionally, we need to cleanup the previous request queues.
--- drivers/block/swim.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/block/swim.c +11 -2
@@ -868,8 +868,17 @@ static int swim_floppy_init(struct swim_priv *swd) exit_put_disks:unregister_blkdev (FLOPPY_MAJOR ,"fd" ); -while (drive--) -put_disk (swd->unit[drive].disk); +do { +struct gendisk *disk = swd->unit[drive].disk; + +if (disk) { +if (disk->queue) { +blk_cleanup_queue (disk->queue); + disk->queue =NULL ; + } +put_disk (disk); + } + }while (drive--);return err; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 4/22 tun: Consistently configure generic netdev params via rtnetlink
In reply to Sasha LevinFrom: Serhey Popovych <[email protected]>
[ Upstream commit df52eab23d703142c766ac00bdb8db19d71238d0 ]
Configuring generic network device parameters on tun will fail in presence of IFLA_INFO_KIND attribute in IFLA_LINKINFO nested attribute since tun_validate() always return failure.
This can be visualized with following ip-link(8) command sequences:
# ip link set dev tun0 group 100 # ip link set dev tun0 group 100 type tun RTNETLINK answers: Invalid argument
with contrast to dummy and veth drivers:
# ip link set dev dummy0 group 100 # ip link set dev dummy0 type dummy
# ip link set dev veth0 group 100 # ip link set dev veth0 group 100 type veth
Fix by returning zero in tun_validate() when @data is NULL that is always in case since rtnl_link_ops->maxtype is zero in tun driver.
--- drivers/net/tun.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/tun.c +2 -0
@@ -1423,6 +1423,8 @@ static void tun_setup(struct net_device *dev)*/ static int tun_validate (struct nlattr *tb[],struct nlattr *data[]) { +if (!data) +return 0 ;return -EINVAL ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 5/22 perf tools: Free temporary 'sys' string in read_event_files()
In reply to Sasha LevinFrom: Sanskriti Sharma <[email protected]>
[ Upstream commit 1e44224fb0528b4c0cc176bde2bb31e9127eb14b ]
For each system in a given pevent, read_event_files() reads in a temporary 'sys' string. Be sure to free this string before moving onto to the next system and/or leaving read_event_files().
Fixes the following coverity complaints:
Error: RESOURCE_LEAK (CWE-772):
tools/perf/util/trace-event-read.c:343: overwrite_var: Overwriting "sys" in "sys = read_string()" leaks the storage that "sys" points to.
tools/perf/util/trace-event-read.c:353: leaked_storage: Variable "sys" going out of scope leaks the storage it points to.
--- tools/perf/util/trace-event-read.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/util/trace-event-read.c +4 -1
@@ -336,9 +336,12 @@ static int read_event_files(struct pevent *pevent)for (x=0 ; x < count; x++) { size =read8 (pevent); ret =read_event_file (pevent, sys, size); -if (ret) +if (ret) { +free (sys);return ret; + } } +free (sys); }return 0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 6/22 perf tools: Cleanup trace-event-info 'tdata' leak
In reply to Sasha LevinFrom: Sanskriti Sharma <[email protected]>
[ Upstream commit faedbf3fd19f2511a39397f76359e4cc6ee93072 ]
Free tracing_data structure in tracing_data_get() error paths.
Fixes the following coverity complaint:
Error: RESOURCE_LEAK (CWE-772):
leaked_storage: Variable "tdata" going out of scope leaks the storage
--- tools/perf/util/trace-event-info.c | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/util/trace-event-info.c +2 -0
@@ -513,12 +513,14 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs, "/tmp/perf-XXXXXX");if (!mkstemp (tdata->temp_file)) {pr_debug ("Can't make temp file" ); +free (tdata);return NULL ; } temp_fd =open (tdata->temp_file,O_RDWR );if (temp_fd <0 ) {pr_debug ("Can't read '%s'" , tdata->temp_file); +free (tdata);return NULL ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 7/22 cpupower: Fix coredump on VMWare
In reply to Sasha LevinFrom: Prarit Bhargava <[email protected]>
[ Upstream commit f69ffc5d3db8f1f03fd6d1df5930f9a1fbd787b6 ]
cpupower crashes on VMWare guests. The guests have the AMD PStateDef MSR (0xC0010064 + state number) set to zero. As a result fid and did are zero and the crash occurs because of a divide by zero (cof = fid/did). This can be prevented by checking the enable bit in the PStateDef MSR before calculating cof. By doing this the value of pstate[i] remains zero and the value can be tested before displaying the active Pstates.
Check the enable bit in the PstateDef register for all supported families and only print out enabled Pstates.
--- tools/power/cpupower/utils/cpufreq-info.c | 2 ++ tools/power/cpupower/utils/helpers/amd.c | 5 +++++ 2 files changed, 7 insertions(+)
tools/power/cpupower/utils/cpufreq-info.c +2 -0
@@ -200,6 +200,8 @@ static int get_boost_mode(unsigned int cpu)printf (_ (" Boost States: %d\n" ), b_states);printf (_ (" Total States: %d\n" ), pstate_no);for (i =0 ; i < pstate_no; i++) { +if (!pstates[i]) +continue ;if (i < b_states)printf (_ (" Pstate-Pb%d: %luMHz (boost state)" "\n" ), i, pstates[i]);
tools/power/cpupower/utils/helpers/amd.c +5 -0
@@ -103,6 +103,11 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, }if (read_msr (cpu,MSR_AMD_PSTATE + i, &pstate.val))return -1 ; +if ((cpu_family ==0x17 ) && (!pstate.fam17h_bits.en)) +continue ; +else if (!pstate.bits.en) +continue ; + pstates[i] =get_cof (cpu_family, pstate); } *no = i;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 8/22 mmc: sdhci-pci-o2micro: Add quirk for O2 Micro dev 0x8620 rev 0x01
In reply to Sasha LevinFrom: Yu Zhao <[email protected]>
[ Upstream commit 5169894982bb67486d93cc1e10151712bb86bcb6 ]
This device reports SDHCI_CLOCK_INT_STABLE even though it's not ready to take SDHCI_CLOCK_CARD_EN. The symptom is that reading SDHCI_CLOCK_CONTROL after enabling the clock shows absence of the bit from the register (e.g. expecting 0x0000fa07 = 0x0000fa03 | SDHCI_CLOCK_CARD_EN but only observed the first operand).
mmc1: Timeout waiting for hardware cmd interrupt.
mmc1: sdhci: ============ SDHCI REGISTER DUMP ===========
mmc1: sdhci: Sys addr: 0x00000000 | Version: 0x00000603
mmc1: sdhci: Blk size: 0x00000000 | Blk cnt: 0x00000000
mmc1: sdhci: Argument: 0x00000000 | Trn mode: 0x00000000
mmc1: sdhci: Present: 0x01ff0001 | Host ctl: 0x00000001
mmc1: sdhci: Power: 0x0000000f | Blk gap: 0x00000000
mmc1: sdhci: Wake-up: 0x00000000 | Clock: 0x0000fa03
mmc1: sdhci: Timeout: 0x00000000 | Int stat: 0x00000000
mmc1: sdhci: Int enab: 0x00ff0083 | Sig enab: 0x00ff0083
mmc1: sdhci: AC12 err: 0x00000000 | Slot int: 0x00000000
mmc1: sdhci: Caps: 0x25fcc8bf | Caps_1: 0x00002077
mmc1: sdhci: Cmd: 0x00000000 | Max curr: 0x005800c8
mmc1: sdhci: Resp[0]: 0x00000000 | Resp[1]: 0x00000000
mmc1: sdhci: Resp[2]: 0x00000000 | Resp[3]: 0x00000000
mmc1: sdhci: Host ctl2: 0x00000008
mmc1: sdhci: ADMA Err: 0x00000000 | ADMA Ptr: 0x00000000
mmc1: sdhci: ============================================
The problem happens during wakeup from S3. Adding a delay quirk after power up reliably fixes the problem.
--- drivers/mmc/host/sdhci-pci-o2micro.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mmc/host/sdhci-pci-o2micro.c +3 -0
@@ -336,6 +336,9 @@ int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)pci_write_config_byte (chip->pdev,O2_SD_LOCK_WP , scratch);break ;case PCI_DEVICE_ID_O2_SEABIRD0 : +if (chip->pdev->revision ==0x01 ) + chip->quirks |=SDHCI_QUIRK_DELAY_AFTER_POWER ; +/* fall through */ case PCI_DEVICE_ID_O2_SEABIRD1 :/* UnLock WP */ ret = pci_read_config_byte(chip->pdev,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 9/22 x86/olpc: Indicate that legacy PC XO-1 platform should not register RTC
In reply to Sasha LevinFrom: Lubomir Rintel <[email protected]>
[ Upstream commit d92116b800fb79a72ad26121f5011f6aa3ad94c2 ]
On OLPC XO-1, the RTC is discovered via device tree from the arch initcall. Don't let the PC platform register another one from its device initcall, it's not going to work:
sysfs: cannot create duplicate filename '/devices/platform/rtc_cmos'
CPU: 0 PID: 1 Comm: swapper Not tainted 4.19.0-rc6 #12
Hardware name: OLPC XO/XO, BIOS OLPC Ver 1.00.01 06/11/2014
Call Trace:
dump_stack+0x16/0x18
sysfs_warn_dup+0x46/0x58
sysfs_create_dir_ns+0x76/0x9b
kobject_add_internal+0xed/0x209
? __schedule+0x3fa/0x447
kobject_add+0x5b/0x66
device_add+0x298/0x535
? insert_resource_conflict+0x2a/0x3e
platform_device_add+0x14d/0x192
? io_delay_init+0x19/0x19
platform_device_register+0x1c/0x1f
add_rtc_cmos+0x16/0x31
do_one_initcall+0x78/0x14a
? do_early_param+0x75/0x75
kernel_init_freeable+0x152/0x1e0
? rest_init+0xa2/0xa2
kernel_init+0x8/0xd5
ret_from_fork+0x2e/0x38
kobject_add_internal failed for rtc_cmos with -EEXIST, don't try to
register things with the same name in the same directory.
platform rtc_cmos: registered platform RTC device (no PNP device found)--- arch/x86/platform/olpc/olpc-xo1-rtc.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/platform/olpc/olpc-xo1-rtc.c +3 -0
@@ -16,6 +16,7 @@#include <asm/msr.h> #include <asm/olpc.h> +#include <asm/x86_init.h> static void rtc_wake_on (struct device *dev) {
@@ -75,6 +76,8 @@ static int __init xo1_rtc_init(void)if (r)return r; + x86_platform.legacy.rtc =0 ; +device_init_wakeup (&xo1_rtc_device.dev,1 );return 0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 10/22 regulator: fixed: Default enable high on DT regulators
In reply to Sasha LevinFrom: Linus Walleij <[email protected]>
[ Upstream commit 28be5f15df2ee6882b0a122693159c96a28203c7 ]
commit efdfeb079cc3
("regulator: fixed: Convert to use GPIO descriptor only") switched to use gpiod_get() to look up the regulator from the gpiolib core whether that is device tree or boardfile.
This meant that we activate the code ina603a2b8d86e ("gpio: of: Add special quirk to parse regulator flags") which means the descriptors coming from the device tree already have the right inversion and open drain semantics set up from the gpiolib core.
As the fixed regulator was inspected again we got the inverted inversion and things broke.
Fix it by ignoring the config in the device tree for now: the later patches in the series will push all inversion handling over to the gpiolib core and set it up properly in the boardfiles for legacy devices, but I did not finish that for this kernel cycle.
--- drivers/regulator/fixed.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/regulator/fixed.c +8 -3
@@ -92,9 +92,14 @@ of_get_fixed_voltage_config(struct device *dev)of_property_read_u32 (np,"startup-delay-us" , &config->startup_delay); - config->enable_high =of_property_read_bool (np,"enable-active-high" ); - config->gpio_is_open_drain =of_property_read_bool (np, -"gpio-open-drain" ); +/* +* FIXME: we pulled active low/high and open drain handling into +* gpiolib so it will be handled there. Delete this in the second +* step when we also remove the custom inversion handling for all +* legacy boardfiles. +*/ + config->enable_high =1 ; + config->gpio_is_open_drain =0 ;if (of_find_property (np,"vin-supply" ,NULL )) config->input_supply ="vin" ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 11/22 x86: boot: Fix EFI stub alignment
In reply to Sasha LevinFrom: Ben Hutchings <[email protected]>
[ Upstream commit 9c1442a9d039a1a3302fa93e9a11001c5f23b624 ]
We currently align the end of the compressed image to a multiple of
16. However, the PE-COFF header included in the EFI stub says that the file alignment is 32 bytes, and when adding an EFI signature to the file it must first be padded to this alignment.
sbsigntool commands warn about this:
warning: file-aligned section .text extends beyond end of file
warning: checksum areas are greater than image size. Invalid section table?
Worse, pesign -at least when creating a detached signature- uses the hash of the unpadded file, resulting in an invalid signature if padding is required.
Avoid both these problems by increasing alignment to 32 bytes when CONFIG_EFI_STUB is enabled.
--- arch/x86/boot/tools/build.c | 7 +++++++ 1 file changed, 7 insertions(+)
arch/x86/boot/tools/build.c +7 -0
@@ -391,6 +391,13 @@ int main(int argc, char ** argv)die ("Unable to mmap '%s': %m" , argv[2 ]);/* Number of 16-byte paragraphs, including space for a 4-byte CRC */ sys_size = (sz +15 +4 ) /16 ; +#ifdef CONFIG_EFI_STUB +/* +* COFF requires minimum 32-byte alignment of sections, and +* adding a signature is problematic without that alignment. +*/ + sys_size = (sys_size +1 ) & ~1 ; +#endif /* Patch the setup code with the appropriate size parameters */ buf[0x1f1 ] = setup_sectors-1 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 12/22 kprobes: Return error if we fail to reuse kprobe instead of BUG_ON()
In reply to Sasha LevinFrom: Masami Hiramatsu <[email protected]>
[ Upstream commit 819319fc93461c07b9cdb3064f154bd8cfd48172 ]
Make reuse_unused_kprobe() to return error code if it fails to reuse unused kprobe for optprobe instead of calling BUG_ON().
--- kernel/kprobes.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
kernel/kprobes.c +20 -7
@@ -665,9 +665,10 @@ static void unoptimize_kprobe(struct kprobe *p, bool force) }/* Cancel unoptimizing for reusing */ -static void reuse_unused_kprobe (struct kprobe *ap) +static int reuse_unused_kprobe (struct kprobe *ap) {struct optimized_kprobe *op; +int ret;BUG_ON (!kprobe_unused (ap));/*
@@ -681,8 +682,12 @@ static void reuse_unused_kprobe(struct kprobe *ap)/* Enable the probe again */ ap->flags &= ~KPROBE_FLAG_DISABLED ;/* Optimize it again (remove from op->list) */ -BUG_ON (!kprobe_optready (ap)); + ret =kprobe_optready (ap); +if (ret) +return ret; +optimize_kprobe (ap); +return 0 ; }/* Remove optimized instructions */
@@ -893,11 +898,16 @@ static void __disarm_kprobe(struct kprobe *p, bool reopt)#define kprobe_disarmed (p) kprobe_disabled(p)#define wait_for_kprobe_optimizer () do {} while (0) -/* There should be no unused kprobes can be reused without optimization */ -static void reuse_unused_kprobe (struct kprobe *ap) +static int reuse_unused_kprobe (struct kprobe *ap) { +/* +* If the optimized kprobe is NOT supported, the aggr kprobe is +* released at the same time that the last aggregated kprobe is +* unregistered. +* Thus there should be no chance to reuse unused kprobe. +*/ printk (KERN_ERR "Error: There should be no unused kprobe here.\n" ); -BUG_ON (kprobe_unused (ap)); +return -EINVAL ; }static void free_aggr_kprobe (struct kprobe *p)
@@ -1275,9 +1285,12 @@ static int register_aggr_kprobe(struct kprobe *orig_p, struct kprobe *p) goto out; }init_aggr_kprobe (ap, orig_p); - }else if (kprobe_unused (ap)) + }else if (kprobe_unused (ap)) {/* This probe is going to die. Rescue it */ -reuse_unused_kprobe (ap); + ret =reuse_unused_kprobe (ap); +if (ret) + goto out; + }if (kprobe_gone (ap)) {/*
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 13/22 ath10k: schedule hardware restart if WMI command times out
In reply to Sasha LevinFrom: Martin Willi <[email protected]>
[ Upstream commit a9911937e7d332761e8c4fcbc7ba0426bdc3956f ]
When running in AP mode, ath10k sometimes suffers from TX credit starvation. The issue is hard to reproduce and shows up once in a few days, but has been repeatedly seen with QCA9882 and a large range of firmwares, including 10.2.4.70.67.
Once the module is in this state, TX credits are never replenished, which results in "SWBA overrun" errors, as no beacons can be sent. Even worse, WMI commands run in a timeout while holding the conf mutex for three seconds each, making any further operations slow and the whole system unresponsive.
The firmware/driver never recovers from that state automatically, and triggering TX flush or warm restarts won't work over WMI. So issue a hardware restart if a WMI command times out due to missing TX credits. This implies a connectivity outage of about 1.4s in AP mode, but brings back the interface and the whole system to a usable state. WMI command timeouts have not been seen in absent of this specific issue, so taking such drastic actions seems legitimate.
--- drivers/net/wireless/ath/ath10k/wmi.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/wireless/ath/ath10k/wmi.c +6 -0
@@ -751,6 +751,12 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)if (ret)dev_kfree_skb_any (skb); +if (ret == -EAGAIN ) { +ath10k_warn (ar,"wmi command %d timeout, restarting hardware\n" , + cmd_id); +queue_work (ar->workqueue, &ar->restart_work); + } +return ret; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 14/22 scsi: esp_scsi: Track residual for PIO transfers
In reply to Sasha LevinFrom: Finn Thain <[email protected]>
[ Upstream commit fd47d919d0c336e7c22862b51ee94927ffea227a ]
If a target disconnects during a PIO data transfer the command may fail when the target reconnects:
scsi host1: DMA length is zero!
scsi host1: cur adr[04380000] len[00000000]
The scsi bus is then reset. This happens because the residual reached zero before the transfer was completed.
The usual residual calculation relies on the Transfer Count registers. That works for DMA transfers but not for PIO transfers. Fix the problem by storing the PIO transfer residual and using that to correctly calculate bytes_sent.
--- drivers/scsi/esp_scsi.c | 1 + drivers/scsi/esp_scsi.h | 2 ++ drivers/scsi/mac_esp.c | 2 ++ 3 files changed, 5 insertions(+)
drivers/scsi/esp_scsi.c +1 -0
@@ -1316,6 +1316,7 @@ static int esp_data_bytes_sent(struct esp *esp, struct esp_cmd_entry *ent, bytes_sent = esp->data_dma_len; bytes_sent -= ecount; + bytes_sent -= esp->send_cmd_residual;if (!(ent->flags &ESP_CMD_FLAG_WRITE )) bytes_sent -= fifo_cnt;
drivers/scsi/esp_scsi.h +2 -0
@@ -524,6 +524,8 @@ struct esp {void *dma;int dmarev; + +u32 send_cmd_residual; };/* A front-end driver for the ESP chip should do the following in
drivers/scsi/mac_esp.c +2 -0
@@ -426,6 +426,8 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,scsi_esp_cmd (esp,ESP_CMD_TI ); } } + + esp->send_cmd_residual = esp_count; }static int mac_esp_irq_pending (struct esp *esp)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 15/22 Drivers: hv: kvp: Fix two "this statement may fall through" warnings
In reply to Sasha LevinFrom: Dexuan Cui <[email protected]>
[ Upstream commit fc62c3b1977d62e6374fd6e28d371bb42dfa5c9d ]
We don't need to call process_ib_ipinfo() if message->kvp_hdr.operation is KVP_OP_GET_IP_INFO in kvp_send_key(), because here we just need to pass on the op code from the host to the userspace; when the userspace returns the info requested by the host, we pass the info on to the host in kvp_respond_to_host() -> process_ob_ipinfo(). BTW, the current buggy code actually doesn't cause any harm, because only message->kvp_hdr.operation is used by the userspace, in the case of KVP_OP_GET_IP_INFO.
The patch also adds a missing "break;" in kvp_send_key(). BTW, the current buggy code actually doesn't cause any harm, because in the case of KVP_OP_SET, the unexpected fall-through corrupts message->body.kvp_set.data.key_size, but that is not really used: see the definition of struct hv_kvp_exchg_msg_value.
--- drivers/hv/hv_kvp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/hv/hv_kvp.c +4 -2
@@ -326,7 +326,6 @@ static void process_ib_ipinfo(void *in_msg, void *out_msg, int op) out->body.kvp_ip_val.dhcp_enabled = in->kvp_ip_val.dhcp_enabled; -default : utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id, MAX_ADAPTER_ID_SIZE, UTF16_LITTLE_ENDIAN,
@@ -379,7 +378,7 @@ kvp_send_key(struct work_struct *dummy)process_ib_ipinfo (in_msg, message,KVP_OP_SET_IP_INFO );break ;case KVP_OP_GET_IP_INFO : -process_ib_ipinfo (in_msg, message,KVP_OP_GET_IP_INFO ); +/* We only need to pass on message->kvp_hdr.operation. */ break ;case KVP_OP_SET :switch (in_msg->body.kvp_set.data.value_type) {
@@ -419,6 +418,9 @@ kvp_send_key(struct work_struct *dummy)break ; } + +break ; +case KVP_OP_GET : message->body.kvp_set.data.key_size = utf16s_to_utf8s(
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 16/22 ext4: fix argument checking in EXT4_IOC_MOVE_EXT
In reply to Sasha LevinFrom: Theodore Ts'o <[email protected]>
[ Upstream commit f18b2b83a727a3db208308057d2c7945f368e625 ]
If the starting block number of either the source or destination file exceeds the EOF, EXT4_IOC_MOVE_EXT should return EINVAL.
Also fixed the helper function mext_check_coverage() so that if the logical block is beyond EOF, make it return immediately, instead of looping until the block number wraps all the away around. This takes long enough that if there are multiple threads trying to do pound on an the same inode doing non-sensical things, it can end up triggering the kernel's soft lockup detector.
--- fs/ext4/move_extent.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
fs/ext4/move_extent.c +6 -2
@@ -533,9 +533,13 @@ mext_check_arguments(struct inode *orig_inode, orig_inode->i_ino, donor_inode->i_ino);return -EINVAL ; } -if (orig_eof < orig_start + *len -1 ) +if (orig_eof <= orig_start) + *len =0 ; +else if (orig_eof < orig_start + *len -1 ) *len = orig_eof - orig_start; -if (donor_eof < donor_start + *len -1 ) +if (donor_eof <= donor_start) + *len =0 ; +else if (donor_eof < donor_start + *len -1 ) *len = donor_eof - donor_start;if (!*len) { ext4_debug("ext4 move extent: len should not be 0 "
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 17/22 MD: fix invalid stored role for a disk
In reply to Sasha LevinFrom: Shaohua Li <[email protected]>
[ Upstream commit d595567dc4f0c1d90685ec1e2e296e2cad2643ac ]
If we change the number of array's device after device is removed from array, then add the device back to array, we can see that device is added as active role instead of spare which we expected.
Please see the below link for details:
https://marc.info/?l=linux-raid&m=153736982015076&w=2
This is caused by that we prefer to use device's previous role which is recorded by saved_raid_disk, but we should respect the new number of conf->raid_disks since it could be changed after device is removed.
--- drivers/md/md.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/md/md.c +4 -0
@@ -1646,6 +1646,10 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) }else set_bit (In_sync, &rdev->flags); rdev->raid_disk = role; +if (role >= mddev->raid_disks) { + rdev->saved_raid_disk =-1 ; + rdev->raid_disk =-1 ; + }break ; }if (sb->devflags & WriteMostly1)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 18/22 usb: chipidea: Prevent unbalanced IRQ disable
In reply to Sasha LevinFrom: Loic Poulain <[email protected]>
[ Upstream commit 8b97d73c4d72a2abf58f8e49062a7ee1e5f1334e ]
The ChipIdea IRQ is disabled before scheduling the otg work and re-enabled on otg work completion. However if the job is already scheduled we have to undo the effect of disable_irq int order to balance the IRQ disable-depth value.
--- drivers/usb/chipidea/otg.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/chipidea/otg.h +2 -1
@@ -20,7 +20,8 @@ void ci_handle_vbus_change(struct ci_hdrc *ci);static inline void ci_otg_queue_work (struct ci_hdrc *ci) {disable_irq_nosync (ci->irq); -queue_work (ci->wq, &ci->work); +if (queue_work (ci->wq, &ci->work) == false) +enable_irq (ci->irq); }#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 19/22 uio: ensure class is registered before devices
In reply to Sasha LevinFrom: Alexandre Belloni <[email protected]>
[ Upstream commit ae61cf5b9913027c6953a79ed3894da4f47061bd ]
When both uio and the uio drivers are built in the kernel, it is possible for a driver to register devices before the uio class is registered.
This may result in a NULL pointer dereference later on in get_device_parent() when accessing the class glue_dirs spinlock.
The trace looks like that:
Unable to handle kernel NULL pointer dereference at virtual address 00000140 [...] [<ffff0000089cc234>] _raw_spin_lock+0x14/0x48 [<ffff0000084f56bc>] device_add+0x154/0x6a0 [<ffff0000084f5e48>] device_create_groups_vargs+0x120/0x128 [<ffff0000084f5edc>] device_create+0x54/0x60 [<ffff0000086e72c0>] __uio_register_device+0x120/0x4a8 [<ffff000008528b7c>] jaguar2_pci_probe+0x2d4/0x558 [<ffff0000083fc18c>] local_pci_probe+0x3c/0xb8 [<ffff0000083fd81c>] pci_device_probe+0x11c/0x180 [<ffff0000084f88bc>] driver_probe_device+0x22c/0x2d8 [<ffff0000084f8a24>] __driver_attach+0xbc/0xc0 [<ffff0000084f69fc>] bus_for_each_dev+0x4c/0x98 [<ffff0000084f81b8>] driver_attach+0x20/0x28 [<ffff0000084f7d08>] bus_add_driver+0x1b8/0x228 [<ffff0000084f93c0>] driver_register+0x60/0xf8 [<ffff0000083fb918>] __pci_register_driver+0x40/0x48
Return EPROBE_DEFER in that case so the driver can register the device later.
--- drivers/uio/uio.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/uio/uio.c +9 -0
@@ -249,6 +249,8 @@ static struct class uio_class = { .dev_groups = uio_groups, }; +bool uio_class_registered; +/* * device functions */
@@ -771,6 +773,9 @@ static int init_uio_class(void)printk (KERN_ERR "class_register failed for uio\n" ); goto err_class_register; } + + uio_class_registered = true; +return 0 ; err_class_register:
@@ -781,6 +786,7 @@ static int init_uio_class(void)static void release_uio_class (void ) { + uio_class_registered = false;class_unregister (&uio_class);uio_major_cleanup (); }
@@ -800,6 +806,9 @@ int __uio_register_device(struct module *owner,struct uio_device *idev;int ret =0 ; +if (!uio_class_registered) +return -EPROBE_DEFER ; +if (!parent || !info || !info->name || !info->version)return -EINVAL ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 20/22 scsi: lpfc: Correct soft lockup when running mds diagnostics
In reply to Sasha LevinFrom: James Smart <[email protected]>
[ Upstream commit 0ef01a2d95fd62bb4f536e7ce4d5e8e74b97a244 ]
When running an mds diagnostic that passes frames with the switch, soft lockups are detected. The driver is in a CQE processing loop and has sufficient amount of traffic that it never exits the ring processing routine, thus the "lockup".
Cap the number of elements in the work processing routine to 64 elements. This ensures that the cpu will be given up and the handler reschedule to process additional items.
--- drivers/scsi/lpfc/lpfc_sli.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/scsi/lpfc/lpfc_sli.c +7 -0
@@ -3441,6 +3441,7 @@ lpfc_sli_handle_slow_ring_event_s4(struct lpfc_hba *phba,struct hbq_dmabuf *dmabuf;struct lpfc_cq_event *cq_event;unsigned long iflag; +int count =0 ;spin_lock_irqsave (&phba->hbalock, iflag); phba->hba_flag &= ~HBA_SP_QUEUE_EVT ;
@@ -3462,16 +3463,22 @@ lpfc_sli_handle_slow_ring_event_s4(struct lpfc_hba *phba,if (irspiocbq)lpfc_sli_sp_handle_rspiocb (phba, pring, irspiocbq); + count++;break ;case CQE_CODE_RECEIVE :case CQE_CODE_RECEIVE_V1 : dmabuf = container_of(cq_event, struct hbq_dmabuf, cq_event);lpfc_sli4_handle_received_buffer (phba, dmabuf); + count++;break ;default :break ; } + +/* Limit the number of events to 64 to avoid soft lockups */ +if (count ==64 ) +break ; } }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 21/22 signal: Always deliver the kernel's SIGKILL and SIGSTOP to a pid namespace init
In reply to Sasha LevinFrom: "Eric W. Biederman" <[email protected]>
[ Upstream commit 3597dfe01d12f570bc739da67f857fd222a3ea66 ]
Instead of playing whack-a-mole and changing SEND_SIG_PRIV to SEND_SIG_FORCED throughout the kernel to ensure a pid namespace init gets signals sent by the kernel, stop allowing a pid namespace init to ignore SIGKILL or SIGSTOP sent by the kernel. A pid namespace init is only supposed to be able to ignore signals sent from itself and children with SIG_DFL.
--- kernel/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/signal.c +1 -1
@@ -1042,7 +1042,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, result =TRACE_SIGNAL_IGNORED ;if (!prepare_signal (sig, t, - from_ancestor_ns || (info ==SEND_SIG_FORCED ))) + from_ancestor_ns || (info ==SEND_SIG_PRIV ) || (info ==SEND_SIG_FORCED ))) goto ret; pending = group ? &t->signal->shared_pending : &t->pending;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 22/22 mfd: menelaus: Fix possible race condition and leak
In reply to Sasha LevinFrom: Alexandre Belloni <[email protected]>
[ Upstream commit 9612f8f503804d2fd2f63aa6ba1e58bba4612d96 ]
The IRQ work is added before the struct rtc is allocated and registered, but this struct is used in the IRQ handler. This may lead to a NULL pointer dereference.
Switch to devm_rtc_allocate_device/rtc_register_device to allocate the rtc before calling menelaus_add_irq_work.
Also, this solves a possible leak as the RTC is never released.
--- drivers/mfd/menelaus.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/mfd/menelaus.c +9 -4
@@ -1121,6 +1121,7 @@ static void menelaus_rtc_alarm_work(struct menelaus_chip *m)static inline void menelaus_rtc_init (struct menelaus_chip *m) {int alarm = (m->client->irq >0 ); +int err;/* assume 32KDETEN pin is pulled high */ if (!(menelaus_read_reg (MENELAUS_OSC_CTRL ) &0x80 )) {
@@ -1128,6 +1129,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)return ; } + m->rtc =devm_rtc_allocate_device (&m->client->dev); +if (IS_ERR (m->rtc)) +return ; + + m->rtc->ops = &menelaus_rtc_ops; +/* support RTC alarm; it can issue wakeups */ if (alarm) { if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ,
@@ -1152,10 +1159,8 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)menelaus_write_reg (MENELAUS_RTC_CTRL , m->rtc_control); } - m->rtc =rtc_device_register (DRIVER_NAME , - &m->client->dev, - &menelaus_rtc_ops,THIS_MODULE ); -if (IS_ERR (m->rtc)) { + err =rtc_register_device (m->rtc); +if (err) {if (alarm) {menelaus_remove_irq_work (MENELAUS_RTCALM_IRQ );device_init_wakeup (&m->client->dev,0 );
Signature · 1 line
2.17.1
Re: [PATCH AUTOSEL 3.18 22/22] mfd: menelaus: Fix possible race condition and leak
Hello,
drivers/mfd/menelaus.c static inline void menelaus_rtc_init(struct menelaus_chip *m) · line 1162
Quoted 5 lines · Sasha Levin
drivers/mfd/menelaus.c +1
-4- m->rtc =rtc_device_register (DRIVER_NAME , - &m->client->dev, - &menelaus_rtc_ops,THIS_MODULE ); -if (IS_ERR (m->rtc)) { + err =rtc_register_device (m->rtc);
This appeared in v4.13, this will not compile on v3.18.
Quoted 7 lines
drivers/mfd/menelaus.c +1
-0+if (err) {if (alarm) {menelaus_remove_irq_work (MENELAUS_RTCALM_IRQ );device_init_wakeup (&m->client->dev,0 );Signature · 1 line
2.17.1
Signature · 3 lines
Alexandre Belloni, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
Sasha Levin
maintainerRe: [PATCH AUTOSEL 3.18 22/22] mfd: menelaus: Fix possible race condition and leak
Quoted 10 lines · Alexandre Belloni
Hello,
drivers/mfd/menelaus.c static inline void menelaus_rtc_init(struct menelaus_chip *m) · line 1162
Quoted 5 lines · Sasha Levin
drivers/mfd/menelaus.c +1
-4- m->rtc =rtc_device_register (DRIVER_NAME , - &m->client->dev, - &menelaus_rtc_ops,THIS_MODULE ); -if (IS_ERR (m->rtc)) { + err =rtc_register_device (m->rtc);This appeared in v4.13, this will not compile on v3.18.
Indeed, I guess I need more cross-compilers here. Thanks!
--
Thanks,
Sasha