perf symbols: Fix memory corruption because of zero length symbols
Subsystems (3)
Sasha Levin
maintainerPATCH 1/98 perf symbols: Fix memory corruption because of zero length symbols
From: Ravi Bangoria <[email protected]>
[ Upstream commit 331c7cb307971eac38e9470340e10c87855bf4bc ]
Perf top is often crashing at very random locations on powerpc. After investigating, I found the crash only happens when sample is of zero length symbol. Powerpc kernel has many such symbols which does not contain length details in vmlinux binary and thus start and end addresses of such symbols are same.
Structure
struct sym_hist {
u64 nr_samples;
u64 period;
struct sym_hist_entry addr[0];
};has last member 'addr[]' of size zero. 'addr[]' is an array of addresses that belongs to one symbol (function). If function consist of 100 instructions, 'addr' points to an array of 100 'struct sym_hist_entry' elements. For zero length symbol, it points to the *empty* array, i.e. no members in the array and thus offset 0 is also invalid for such array.
static int __symbol__inc_addr_samples(...)
{
...
offset = addr - sym->start;
h = annotation__histogram(notes, evidx);
h->nr_samples++;
h->addr[offset].nr_samples++;
h->period += sample->period;
h->addr[offset].period += sample->period;
...
}Here, when 'addr' is same as 'sym->start', 'offset' becomes 0, which is valid for normal symbols but *invalid* for zero length symbols and thus updating h->addr[offset] causes memory corruption.
Fix this by adding one dummy element for zero length symbols.
--- tools/perf/util/annotate.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
tools/perf/util/annotate.c +11 -1
@@ -495,9 +495,19 @@ static struct ins *ins__find(const char *name)int symbol__alloc_hist (struct symbol *sym) {struct annotation *notes =symbol__annotation (sym); -const size_t size =symbol__size (sym); +size_t size =symbol__size (sym);size_t sizeof_sym_hist; +/* +* Add buffer of one element for zero length symbol. +* When sample is taken from first instruction of +* zero length symbol, perf still resolves it and +* shows symbol name in perf report and allows to +* annotate it. +*/ +if (size ==0 ) + size =1 ; +/* Check for overflow when calculating sizeof_sym_hist */ if (size > (SIZE_MAX -sizeof (struct sym_hist )) /sizeof (u64))return -1 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 2/98 mm/memory_hotplug.c: fix overflow in test_pages_in_a_zone()
From: zhong jiang <[email protected]>
[ Upstream commit d6d8c8a48291b929b2e039f220f0b62958cccfea ]
When mainline introduced commit a96dfddbcc04 ("base/memory, hotplug: fix a kernel oops in show_valid_zones()"), it obtained the valid start and end pfn from the given pfn range. The valid start pfn can fix the actual issue, but it introduced another issue. The valid end pfn will may exceed the given end_pfn.
Although the incorrect overflow will not result in actual problem at present, but I think it need to be fixed.
--- mm/memory_hotplug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/memory_hotplug.c +2 -2
@@ -1508,7 +1508,7 @@ int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn,while ((i <MAX_ORDER_NR_PAGES ) && !pfn_valid_within (pfn + i)) i++; -if (i ==MAX_ORDER_NR_PAGES ) +if (i ==MAX_ORDER_NR_PAGES || pfn + i >= end_pfn)continue ; page =pfn_to_page (pfn + i);if (zone &&page_zone (page) != zone)
@@ -1522,7 +1522,7 @@ int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn,if (zone) { *valid_start = start; - *valid_end = end; + *valid_end =min (end, end_pfn);return 1 ; }else {return 0 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 3/98 MIPS: microMIPS: Fix decoding of swsp16 instruction
In reply to Sasha LevinFrom: Matt Redfearn <[email protected]>
[ Upstream commit cea8cd498f4f1c30ea27e3664b3c671e495c4fce ]
When the immediate encoded in the instruction is accessed, it is sign extended due to being a signed value being assigned to a signed integer. The ISA specifies that this operation is an unsigned operation. The sign extension leads us to incorrectly decode:
801e9c8e: cbf1 sw ra,68(sp)
As having an immediate of 1073741809.
Since the instruction format does not specify signed/unsigned, and this is currently the only location to use this instuction format, change it to an unsigned immediate.
Patchwork: https://patchwork.linux-mips.org/patch/16957/
--- arch/mips/include/uapi/asm/inst.h | 2 +- arch/mips/kernel/process.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/mips/include/uapi/asm/inst.h +1 -1
@@ -964,7 +964,7 @@ struct mm16_r3_format { /* Load from global pointer format */ struct mm16_r5_format { /* Load/store from stack pointer format */ __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, - __BITFIELD_FIELD(signed int simmediate : 5, + __BITFIELD_FIELD(unsigned int imm : 5, __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ ;)))) };
arch/mips/kernel/process.c +1 -1
@@ -212,7 +212,7 @@ static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)if (ip->mm16_r5_format.rt !=31 )return 0 ; - *poff = ip->mm16_r5_format.simmediate; + *poff = ip->mm16_r5_format.imm; *poff = (*poff <<2 ) /sizeof (ulong);return 1 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 4/98 MIPS: Handle non word sized instructions when examining frame
In reply to Sasha LevinFrom: Matt Redfearn <[email protected]>
[ Upstream commit 11887ed172a6960673f130dad8f8fb42778f64d7 ]
Commit 34c2f668d0f6b ("MIPS: microMIPS: Add unaligned access support.") added fairly broken support for handling 16bit microMIPS instructions in get_frame_info(). It adjusts the instruction pointer by 16bits in the case of a 16bit sp move instruction, but not any other 16bit instruction.
Commit b6c7a324df37 ("MIPS: Fix get_frame_info() handling of microMIPS function size") goes some way to fixing get_frame_info() to iterate over microMIPS instuctions, but the instruction pointer is still manipulated using a postincrement, and is of union mips_instruction type. Since the union is sized to the largest member (a word), but microMIPS instructions are a mix of halfword and word sizes, the function does not always iterate correctly, ending up misaligned with the instruction stream and interpreting it incorrectly.
Since the instruction modifying the stack pointer is usually the first in the function, that one is usually handled correctly. But the instruction which saves the return address to the sp is some variable number of instructions into the frame and is frequently missed due to not being on a word boundary, leading to incomplete walking of the stack.
Fix this by incrementing the instruction pointer based on the size of the previously decoded instruction (& remove the hack introduced by commit 34c2f668d0f6b ("MIPS: microMIPS: Add unaligned access support.") which adjusts the instruction pointer in the case of a 16bit sp move instruction, but not any other).
Patchwork: https://patchwork.linux-mips.org/patch/16953/
--- arch/mips/kernel/process.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/mips/kernel/process.c +6 -3
@@ -346,6 +346,7 @@ static int get_frame_info(struct mips_frame_info *info)bool is_mmips =IS_ENABLED (CONFIG_CPU_MICROMIPS );union mips_instruction insn, *ip, *ip_end;const unsigned int max_insns =128 ; +unsigned int last_insn_size =0 ;unsigned int i; info->pc_offset =-1 ;
@@ -357,15 +358,19 @@ static int get_frame_info(struct mips_frame_info *info) ip_end = (void *)ip + info->func_size; -for (i =0 ; i < max_insns && ip < ip_end; i++, ip++) { +for (i =0 ; i < max_insns && ip < ip_end; i++) { + ip = (void *)ip + last_insn_size;if (is_mmips &&mm_insn_16bit (ip->halfword[0 ])) { insn.halfword[0 ] =0 ; insn.halfword[1 ] = ip->halfword[0 ]; + last_insn_size =2 ; }else if (is_mmips) { insn.halfword[0 ] = ip->halfword[1 ]; insn.halfword[1 ] = ip->halfword[0 ]; + last_insn_size =4 ; }else { insn.word = ip->word; + last_insn_size =4 ; }if (is_jump_ins (&insn))
@@ -387,8 +392,6 @@ static int get_frame_info(struct mips_frame_info *info) tmp = (ip->halfword[0 ] >>1 ); info->frame_size = -(signed short)(tmp & 0xf); } - ip = (void *) &ip->halfword[1 ]; - ip--; } else#endif info->frame_size = - ip->i_format.simmediate;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 5/98 scsi: aacraid: Fix typo in blink status
In reply to Sasha LevinFrom: Raghava Aditya Renukunta <[email protected]>
[ Upstream commit 934767c56b0d9dbb95a40e9e6e4d9dcdc3a165ad ]
The return status of the adapter check on KERNEL_PANIC is supposed to be the upper 16 bits of the OMR status register.
--- drivers/scsi/aacraid/src.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/aacraid/src.c +1 -1
@@ -445,7 +445,7 @@ static int aac_src_check_health(struct aac_dev *dev)return -1 ; err_blink: -return (status >16 ) &0xFF ; +return (status >>16 ) &0xFF ; }/**
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 6/98 f2fs: fix multiple f2fs_add_link() having same name for inline dentry
In reply to Sasha LevinFrom: Sheng Yong <[email protected]>
[ Upstream commit d3bb910c15d75ee3340311c64a1c05985bb663a3 ]
Commit 88c5c13a5027 (f2fs: fix multiple f2fs_add_link() calls having same name) does not cover the scenario where inline dentry is enabled. In that case, F2FS_I(dir)->task will be NULL, and __f2fs_add_link will lookup dentries one more time.
This patch fixes it by moving the assigment of current task to a upper level to cover both normal and inline dentry.
--- fs/f2fs/dir.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
fs/f2fs/dir.c +6 -7
@@ -212,13 +212,9 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir,f2fs_put_page (dentry_page,0 ); } -/* This is to increase the speed of f2fs_create */ -if (!de && room) { -F2FS_I (dir)->task = current; -if (F2FS_I (dir)->chash != namehash) { -F2FS_I (dir)->chash = namehash; -F2FS_I (dir)->clevel = level; - } +if (!de && room &&F2FS_I (dir)->chash != namehash) { +F2FS_I (dir)->chash = namehash; +F2FS_I (dir)->clevel = level; }return de;
@@ -259,6 +255,9 @@ struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir,break ; } out: +/* This is to increase the speed of f2fs_create */ +if (!de) +F2FS_I (dir)->task = current;return de; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 7/98 igb: Remove superfluous reset to PHY and page 0 selection
In reply to Sasha LevinFrom: Christian Grönke <[email protected]>
[ Upstream commit 2a83fba6cae89dd9c0625e68ff8ffff791c67ac0 ]
This patch reverts two previous applied patches to fix an issue that appeared when using SGMII based SFP modules. In the current state the driver will try to reset the PHY before obtaining the phy_addr of the SGMII attached PHY. That leads to an error in e1000_write_phy_reg_sgmii_82575. Causing the initialization to fail:
igb: Intel(R) Gigabit Ethernet Network Driver - version 5.4.0-k
igb: Copyright (c) 2007-2014 Intel Corporation.
igb: probe of ????:??:??.? failed with error -3The patches being reverted are:
commit 182785335447957409282ca745aa5bc3968facee
Author: Aaron Sierra <[email protected]>
Date: Tue Nov 29 10:03:56 2016 -0600
igb: reset the PHY before reading the PHY ID
commit 440aeca4b9858248d8f16d724d9fa87a4f65fa33
Author: Matwey V Kornilov <[email protected]>
Date: Thu Nov 24 13:32:48 2016 +0300
igb: Explicitly select page 0 at initialization
The first reverted patch directly causes the problem mentioned above. In case of SGMII the phy_addr is not known at this point and will only be obtained by 'igb_get_phy_id_82575' further down in the code. The second removed patch selects forces selection of page 0 in the PHY. Something that the reset tries to address as well.
As pointed out by Alexander Duzck, the patch below fixes the same issue but in the proper location:
commit 4e684f59d760a2c7c716bb60190783546e2d08a1
Author: Chris J Arges <[email protected]>
Date: Wed Nov 2 09:13:42 2016 -0500
igb: Workaround for igb i210 firmware issue
Reverts: 440aeca4b9858248d8f16d724d9fa87a4f65fa33.
Reverts: 182785335447957409282ca745aa5bc3968facee.
--- drivers/net/ethernet/intel/igb/e1000_82575.c | 12 ------------ 1 file changed, 12 deletions(-)
drivers/net/ethernet/intel/igb/e1000_82575.c +0 -12
@@ -245,19 +245,7 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw) hw->bus.func = (rd32 (E1000_STATUS ) &E1000_STATUS_FUNC_MASK ) >>E1000_STATUS_FUNC_SHIFT ; -/* Make sure the PHY is in a good state. Several people have reported -* firmware leaving the PHY's page select register set to something -* other than the default of zero, which causes the PHY ID read to -* access something other than the intended register. -*/ - ret_val = hw->phy.ops.reset (hw); -if (ret_val) { -hw_dbg ("Error resetting the PHY.\n" ); - goto out; - } -/* Set phy->phy_addr and phy->id. */ -igb_write_phy_reg_82580 (hw,I347AT4_PAGE_SELECT ,0 ); ret_val =igb_get_phy_id_82575 (hw);if (ret_val)return ret_val;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 8/98 ACPI: sysfs: Make ACPI GPE mask kernel parameter cover all GPEs
In reply to Sasha LevinFrom: Prarit Bhargava <[email protected]>
[ Upstream commit 0f27cff8597d86f881ea8274b49b63b678c14a3c ]
The acpi_mask_gpe= kernel parameter documentation states that the range of mask is 128 GPEs (0x00 to 0x7F). The acpi_masked_gpes mask is a u64 so only 64 GPEs (0x00 to 0x3F) can really be masked.
Use a bitmap of size 0xFF instead of a u64 for the GPE mask so 256 GPEs can be masked.
--- Documentation/kernel-parameters.txt | 1 - drivers/acpi/sysfs.c | 26 ++++++++------------------ 2 files changed, 8 insertions(+), 19 deletions(-)
Documentation/kernel-parameters.txt +0 -1
@@ -313,7 +313,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. This facility can be used to prevent such uncontrolled GPE floodings. Format: <int> - Support masking of GPEs numbered from 0x00 to 0x7f. acpi_no_auto_serialize [HW,ACPI] Disable auto-serialization of AML methods
drivers/acpi/sysfs.c +8 -18
@@ -724,14 +724,8 @@ static ssize_t counter_set(struct kobject *kobj,* interface: * echo unmask > /sys/firmware/acpi/interrupts/gpe00 */ - -/* -* Currently, the GPE flooding prevention only supports to mask the GPEs -* numbered from 00 to 7f. -*/ -#define ACPI_MASKABLE_GPE_MAX 0x80 - -static u64 __initdata acpi_masked_gpes; +#define ACPI_MASKABLE_GPE_MAX 0xFF +static DECLARE_BITMAP(acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) __initdata;static int __init acpi_gpe_set_masked_gpes (char *val) {
@@ -739,7 +733,7 @@ static int __init acpi_gpe_set_masked_gpes(char *val)if (kstrtou8 (val,0 , &gpe) || gpe >ACPI_MASKABLE_GPE_MAX )return -EINVAL ; - acpi_masked_gpes |= ((u64 )1 <<gpe); +set_bit (gpe, acpi_masked_gpes_map);return 1 ; }
@@ -751,15 +745,11 @@ void __init acpi_gpe_apply_masked_gpes(void)acpi_status status;u8 gpe; -for (gpe =0 ; - gpe <min_t (u8,ACPI_MASKABLE_GPE_MAX , acpi_current_gpe_count); - gpe++) { -if (acpi_masked_gpes & ((u64 )1 <<gpe)) { - status =acpi_get_gpe_device (gpe, &handle); -if (ACPI_SUCCESS (status)) { -pr_info ("Masking GPE 0x%x.\n" , gpe); - (void )acpi_mask_gpe (handle, gpe, TRUE); - } +for_each_set_bit (gpe, acpi_masked_gpes_map,ACPI_MASKABLE_GPE_MAX ) { + status =acpi_get_gpe_device (gpe, &handle); +if (ACPI_SUCCESS (status)) { +pr_info ("Masking GPE 0x%x.\n" , gpe); + (void )acpi_mask_gpe (handle, gpe, TRUE); } } }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 9/98 PCI: Disable MSI for HiSilicon Hip06/Hip07 only in Root Port mode
In reply to Sasha LevinFrom: Dongdong Liu <[email protected]>
[ Upstream commit deb86999323661c019ef2740eb9d479d1e526b5c ]
HiSilicon Hip06/Hip07 can operate as either a Root Port or an Endpoint. It always advertises an MSI capability, but it can only generate MSIs when in Endpoint mode.
The device has the same Vendor and Device IDs in both modes, so check the Class Code and disable MSI only when operating as a Root Port.
--- drivers/pci/quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/quirks.c +1 -1
@@ -1634,8 +1634,8 @@ static void quirk_pcie_mch(struct pci_dev *pdev)DECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_INTEL_E7520_MCH , quirk_pcie_mch);DECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_INTEL_E7320_MCH , quirk_pcie_mch);DECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_INTEL_E7525_MCH , quirk_pcie_mch); -DECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_HUAWEI ,0x1610 , quirk_pcie_mch); +DECLARE_PCI_FIXUP_CLASS_FINAL (PCI_VENDOR_ID_HUAWEI ,0x1610 ,PCI_CLASS_BRIDGE_PCI ,8 , quirk_pcie_mch);/* * It's possible for the MSI to get corrupted if shpc and acpi
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 10/98 i2c: bcm2835: Avoid possible NULL ptr dereference
In reply to Sasha LevinFrom: Stefan Wahren <[email protected]>
[ Upstream commit ababb08938df7ac245d30a58b95b94ecf8dc04fc ]
Since commit e2474541032d ("bcm2835: Fix hang for writing messages larger than 16 bytes") the interrupt handler is prone to a possible NULL pointer dereference. This could happen if an interrupt fires before curr_msg is set by bcm2835_i2c_xfer_msg() and randomly occurs on the RPi 3. Even this is an unexpected behavior the driver must handle that with an error instead of a crash.
--- drivers/i2c/busses/i2c-bcm2835.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/i2c/busses/i2c-bcm2835.c +3 -1
@@ -128,7 +128,9 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) }if (val &BCM2835_I2C_S_DONE ) { -if (i2c_dev->curr_msg->flags &I2C_M_RD ) { +if (!i2c_dev->curr_msg) { +dev_err (i2c_dev->dev,"Got unexpected interrupt (from firmware?)\n" ); + }else if (i2c_dev->curr_msg->flags &I2C_M_RD ) {bcm2835_drain_rxfifo (i2c_dev); val =bcm2835_i2c_readl (i2c_dev,BCM2835_I2C_S ); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 11/98 efi/fb: Correct PCI_STD_RESOURCE_END usage
In reply to Sasha LevinFrom: Bjorn Helgaas <[email protected]>
[ Upstream commit 92a16c86299c64f58f320e491977408ba31b8c3c ]
PCI_STD_RESOURCE_END is (confusingly) the index of the last valid BAR, not the *number* of BARs. To iterate through all possible BARs, we need to include PCI_STD_RESOURCE_END.
--- drivers/video/fbdev/efifb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/fbdev/efifb.c +1 -1
@@ -375,7 +375,7 @@ static void efifb_fixup_resources(struct pci_dev *dev)if (!base)return ; -for (i =0 ; i <PCI_STD_RESOURCE_END ; i++) { +for (i =0 ; i <=PCI_STD_RESOURCE_END ; i++) {struct resource *res = &dev->resource[i];if (!(res->flags &IORESOURCE_MEM ))
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 12/98 ipv6: set rt6i_protocol properly in the route when it is installed
In reply to Sasha LevinFrom: Xin Long <[email protected]>
[ Upstream commit b91d532928dff2141ea9c107c3e73104d9843767 ]
After commit c2ed1880fd61 ("net: ipv6: check route protocol when deleting routes"), ipv6 route checks rt protocol when trying to remove a rt entry.
It introduced a side effect causing 'ip -6 route flush cache' not to work well. When flushing caches with iproute, all route caches get dumped from kernel then removed one by one by sending DELROUTE requests to kernel for each cache.
The thing is iproute sends the request with the cache whose proto is set with RTPROT_REDIRECT by rt6_fill_node() when kernel dumps it. But in kernel the rt_cache protocol is still 0, which causes the cache not to be matched and removed.
So the real reason is rt6i_protocol in the route is not set when it is allocated. As David Ahern's suggestion, this patch is to set rt6i_protocol properly in the route when it is installed and remove the codes setting rtm_protocol according to rt6i_flags in rt6_fill_node.
This is also an improvement to keep rt6i_protocol consistent with rtm_protocol.
--- net/ipv6/route.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
net/ipv6/route.c +3 -8
@@ -2289,6 +2289,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buif (on_link) nrt->rt6i_flags &= ~RTF_GATEWAY ; + nrt->rt6i_protocol =RTPROT_REDIRECT ; nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key;if (ip6_ins_rt (nrt))
@@ -2393,6 +2394,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net, .fc_dst_len = prefixlen, .fc_flags =RTF_GATEWAY |RTF_ADDRCONF |RTF_ROUTEINFO | RTF_UP | RTF_PREF(pref), + .fc_protocol = RTPROT_RA, .fc_nlinfo.portid = 0, .fc_nlinfo.nlh = NULL, .fc_nlinfo.nl_net = net,
@@ -2445,6 +2447,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr, .fc_ifindex = dev->ifindex, .fc_flags =RTF_GATEWAY |RTF_ADDRCONF |RTF_DEFAULT | RTF_UP | RTF_EXPIRES | RTF_PREF(pref), + .fc_protocol = RTPROT_RA, .fc_nlinfo.portid = 0, .fc_nlinfo.nlh = NULL, .fc_nlinfo.nl_net = dev_net(dev),
@@ -3241,14 +3244,6 @@ static int rt6_fill_node(struct net *net, } rtm->rtm_scope =RT_SCOPE_UNIVERSE ; rtm->rtm_protocol = rt->rt6i_protocol; -if (rt->rt6i_flags &RTF_DYNAMIC ) - rtm->rtm_protocol =RTPROT_REDIRECT ; -else if (rt->rt6i_flags &RTF_ADDRCONF ) { -if (rt->rt6i_flags & (RTF_DEFAULT |RTF_ROUTEINFO )) - rtm->rtm_protocol =RTPROT_RA ; -else - rtm->rtm_protocol =RTPROT_KERNEL ; - }if (rt->rt6i_flags &RTF_CACHE ) rtm->rtm_flags |=RTM_F_CLONED ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 13/98 platform/x86: acer-wmi: setup accelerometer when ACPI device was found
In reply to Sasha LevinFrom: "Lee, Chun-Yi" <[email protected]>
[ Upstream commit f9ac89f5ad613b462339e845aeb8494646fd9be2 ]
The 98d610c3739a patch was introduced since v4.11-rc1 that it causes that the accelerometer input device will not be created on workable machines because the HID string comparing logic is wrong.
And, the patch doesn't prevent that the accelerometer input device be created on the machines that have no BST0001. That's because the acpi_get_devices() returns success even it didn't find any match device.
This patch fixed the HID string comparing logic of BST0001 device. And, it also makes sure that the acpi_get_devices() returns acpi_handle for BST0001.
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=193761
--- drivers/platform/x86/acer-wmi.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/platform/x86/acer-wmi.c +4 -5
@@ -1856,7 +1856,7 @@ static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level,if (!strcmp (ctx,"SENR" )) {if (acpi_bus_get_device (ah, &dev))return AE_OK ; -if (!strcmp (ACER_WMID_ACCEL_HID ,acpi_device_hid (dev))) +if (strcmp (ACER_WMID_ACCEL_HID ,acpi_device_hid (dev)))return AE_OK ; }else return AE_OK ;
@@ -1877,8 +1877,7 @@ static int __init acer_wmi_get_handle(const char *name, const char *prop, handle =NULL ; status =acpi_get_devices (prop, acer_wmi_get_handle_cb, (void *)name, &handle); - -if (ACPI_SUCCESS (status)) { +if (ACPI_SUCCESS (status) && handle) { *ah = handle;return 0 ; }else {
@@ -2247,8 +2246,8 @@ static int __init acer_wmi_init(void)if (err)return err; err =acer_wmi_accel_setup (); -if (err) -return err; +if (err && err != -ENODEV ) +pr_warn ("Cannot enable accelerometer\n" ); } err =platform_driver_register (&acer_platform_driver);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 14/98 IB/ipoib: Do not warn if IPoIB debugfs doesn't exist
In reply to Sasha LevinFrom: Alaa Hleihel <[email protected]>
[ Upstream commit 14fa91e0fef8e4d6feb8b1fa2a807828e0abe815 ]
netdev_wait_allrefs() could rebroadcast NETDEV_UNREGISTER event multiple times until all refs are gone, which will result in calling ipoib_delete_debug_files multiple times and printing a warning.
Remove the WARN_ONCE since checks of NULL pointers before calling debugfs_remove are not needed.
--- drivers/infiniband/ulp/ipoib/ipoib_fs.c | 2 -- 1 file changed, 2 deletions(-)
drivers/infiniband/ulp/ipoib/ipoib_fs.c +0 -2
@@ -281,8 +281,6 @@ void ipoib_delete_debug_files(struct net_device *dev) {struct ipoib_dev_priv *priv =netdev_priv (dev); -WARN_ONCE (!priv->mcg_dentry,"null mcg debug file\n" ); -WARN_ONCE (!priv->path_dentry,"null path debug file\n" );debugfs_remove (priv->mcg_dentry);debugfs_remove (priv->path_dentry); priv->mcg_dentry = priv->path_dentry =NULL ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 15/98 IB/core: Fix the validations of a multicast LID in attach or detach operations
In reply to Sasha LevinFrom: Noa Osherovich <[email protected]>
[ Upstream commit 5236333592244557a19694a51337df6ac018f0a7 ]
RoCE Annex (A16.9.10/11) declares that during attach (detach) QP to a multicast group, if the QP is associated with a RoCE port, the multicast group MLID is unused and is ignored.
During attach or detach multicast, when the QP is associated with a port, it is enough to check the port's link layer and validate the LID only if it is Infiniband. Otherwise, avoid validating the multicast LID.
--- drivers/infiniband/core/verbs.c | 44 ++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-)
drivers/infiniband/core/verbs.c +40 -4
@@ -1510,6 +1510,44 @@ EXPORT_SYMBOL(ib_dealloc_fmr);/* Multicast groups */ +static bool is_valid_mcast_lid (struct ib_qp *qp,u16 lid) +{ +struct ib_qp_init_attr init_attr = {}; +struct ib_qp_attr attr = {}; +int num_eth_ports =0 ; +int port; + +/* If QP state >= init, it is assigned to a port and we can check this +* port only. +*/ +if (!ib_query_qp (qp, &attr,IB_QP_STATE |IB_QP_PORT , &init_attr)) { +if (attr.qp_state >=IB_QPS_INIT ) { +if (qp->device->get_link_layer (qp->device, attr.port_num) != +IB_LINK_LAYER_INFINIBAND ) +return true; + goto lid_check; + } + } + +/* Can't get a quick answer, iterate over all ports */ +for (port =0 ; port < qp->device->phys_port_cnt; port++) +if (qp->device->get_link_layer (qp->device, port) != +IB_LINK_LAYER_INFINIBAND ) + num_eth_ports++; + +/* If we have at lease one Ethernet port, RoCE annex declares that +* multicast LID should be ignored. We can't tell at this step if the +* QP belongs to an IB or Ethernet port. +*/ +if (num_eth_ports) +return true; + +/* If all the ports are IB, we can check according to IB spec. */ +lid_check: +return !(lid <be16_to_cpu (IB_MULTICAST_LID_BASE ) || + lid ==be16_to_cpu (IB_LID_PERMISSIVE )); +} +int ib_attach_mcast (struct ib_qp *qp,union ib_gid *gid,u16 lid) {int ret;
@@ -1517,8 +1555,7 @@ int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)if (!qp->device->attach_mcast)return -ENOSYS ;if (gid->raw[0 ] !=0xff || qp->qp_type !=IB_QPT_UD || - lid <be16_to_cpu (IB_MULTICAST_LID_BASE ) || - lid ==be16_to_cpu (IB_LID_PERMISSIVE )) + !is_valid_mcast_lid (qp, lid))return -EINVAL ; ret = qp->device->attach_mcast (qp, gid, lid);
@@ -1535,8 +1572,7 @@ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)if (!qp->device->detach_mcast)return -ENOSYS ;if (gid->raw[0 ] !=0xff || qp->qp_type !=IB_QPT_UD || - lid <be16_to_cpu (IB_MULTICAST_LID_BASE ) || - lid ==be16_to_cpu (IB_LID_PERMISSIVE )) + !is_valid_mcast_lid (qp, lid))return -EINVAL ; ret = qp->device->detach_mcast (qp, gid, lid);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 16/98 orangefs: off by ones in xattr size checks
In reply to Sasha LevinFrom: Dan Carpenter <[email protected]>
[ Upstream commit 5f13e58767a53ebb54265e03c0c4a67650286263 ]
A previous patch which claimed to remove off by ones actually introduced them.
strlen() returns the length of the string not including the NUL character. We are using strcpy() to copy "name" into a buffer which is ORANGEFS_MAX_XATTR_NAMELEN characters long. We should make sure to leave space for the NUL, otherwise we're writing one character beyond the end of the buffer.
--- fs/orangefs/xattr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/orangefs/xattr.c +3 -3
@@ -76,7 +76,7 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *name,if (S_ISLNK (inode->i_mode))return -EOPNOTSUPP ; -if (strlen (name) >ORANGEFS_MAX_XATTR_NAMELEN ) +if (strlen (name) >=ORANGEFS_MAX_XATTR_NAMELEN )return -EINVAL ; fsuid =from_kuid (&init_user_ns,current_fsuid ());
@@ -169,7 +169,7 @@ static int orangefs_inode_removexattr(struct inode *inode, const char *name,struct orangefs_kernel_op_s *new_op =NULL ;int ret = -ENOMEM ; -if (strlen (name) >ORANGEFS_MAX_XATTR_NAMELEN ) +if (strlen (name) >=ORANGEFS_MAX_XATTR_NAMELEN )return -EINVAL ;down_write (&orangefs_inode->xattr_sem);
@@ -233,7 +233,7 @@ int orangefs_inode_setxattr(struct inode *inode, const char *name,if (size >ORANGEFS_MAX_XATTR_VALUELEN )return -EINVAL ; -if (strlen (name) >ORANGEFS_MAX_XATTR_NAMELEN ) +if (strlen (name) >=ORANGEFS_MAX_XATTR_NAMELEN )return -EINVAL ; internal_flag =convert_to_internal_xattr_flags (flags);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 17/98 rxe: Fix a sleep-in-atomic bug in post_one_send
In reply to Sasha LevinFrom: Jia-Ju Bai <[email protected]>
[ Upstream commit 07d432bb97f19dd5e784175152f9fce3b2646133 ]
The driver may sleep under a spin lock, and the function call path is:post_one_send (acquire the lock by spin_lock_irqsave)
init_send_wqe
copy_from_user --> may sleep
There is no flow that makes "qp->is_user" true, and copy_from_user may cause bug when a non-user pointer is used. So the lines of copy_from_user and check of "qp->is_user" are removed.
--- drivers/infiniband/sw/rxe/rxe_verbs.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/infiniband/sw/rxe/rxe_verbs.c +2 -7
@@ -729,13 +729,8 @@ static int init_send_wqe(struct rxe_qp *qp, struct ib_send_wr *ibwr, sge = ibwr->sg_list;for (i =0 ; i < num_sge; i++, sge++) { -if (qp->is_user &©_from_user (p, (__user void *) - (uintptr_t )sge->addr, sge->length)) -return -EFAULT ; - -else if (!qp->is_user) -memcpy (p, (void *)(uintptr_t )sge->addr, - sge->length); +memcpy (p, (void *)(uintptr_t )sge->addr, + sge->length); p += sge->length; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 18/98 nvme-pci: fix CMB sysfs file removal in reset path
In reply to Sasha LevinFrom: Max Gurtovoy <[email protected]>
[ Upstream commit 1c78f7735b2bdd0afbe5d14c5c8b6d8d381b6f13 ]
Currently we create the sysfs entry even if we fail mapping it. In that case, the unmapping will not remove the sysfs created file. There is no good reason to create a sysfs entry for a non working CMB and show his characteristics.
--- drivers/nvme/host/pci.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-)
drivers/nvme/host/pci.c +7 -11
@@ -1393,11 +1393,9 @@ static inline void nvme_release_cmb(struct nvme_dev *dev)if (dev->cmb) {iounmap (dev->cmb); dev->cmb =NULL ; -if (dev->cmbsz) { -sysfs_remove_file_from_group (&dev->ctrl.device->kobj, - &dev_attr_cmb.attr,NULL ); - dev->cmbsz =0 ; - } +sysfs_remove_file_from_group (&dev->ctrl.device->kobj, + &dev_attr_cmb.attr,NULL ); + dev->cmbsz =0 ; } }
@@ -1632,16 +1630,14 @@ static int nvme_pci_enable(struct nvme_dev *dev)/* * CMBs can currently only exist on >=1.2 PCIe devices. We only -* populate sysfs if a CMB is implemented. Note that we add the -* CMB attribute to the nvme_ctrl kobj which removes the need to remove -* it on exit. Since nvme_dev_attrs_group has no name we can pass -* NULL as final argument to sysfs_add_file_to_group. +* populate sysfs if a CMB is implemented. Since nvme_dev_attrs_group +* has no name we can pass NULL as final argument to +* sysfs_add_file_to_group. */ if (readl (dev->bar +NVME_REG_VS ) >=NVME_VS (1 ,2 ,0 )) { dev->cmb =nvme_map_cmb (dev); - -if (dev->cmbsz) { +if (dev->cmb) {if (sysfs_add_file_to_group (&dev->ctrl.device->kobj, &dev_attr_cmb.attr,NULL )) dev_warn(dev->dev,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 19/98 net: phy: marvell: Limit 88m1101 autoneg errata to 88E1145 as well.
In reply to Sasha LevinFrom: Zhao Qiang <[email protected]>
[ Upstream commit c505873eaece2b4aefd07d339dc7e1400e0235ac ]
88E1145 also need this autoneg errata.
--- drivers/net/phy/marvell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/phy/marvell.c +1 -1
@@ -1610,7 +1610,7 @@ static struct phy_driver marvell_drivers[] = { .flags = PHY_HAS_INTERRUPT, .probe = marvell_probe, .config_init = &m88e1145_config_init, - .config_aneg = &marvell_config_aneg, + .config_aneg = &m88e1101_config_aneg, .read_status = &genphy_read_status, .ack_interrupt = &marvell_ack_interrupt, .config_intr = &marvell_config_intr,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 20/98 net/mlx5: Fix command completion after timeout access invalid structure
In reply to Sasha LevinFrom: Moshe Shemesh <[email protected]>
[ Upstream commit 061870800efb4e3d1ad4082a2569363629bdfcfc ]
Completion on timeout should not free the driver command entry structure as it will need to access it again once real completion event from FW will occur.
--- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/cmd.c +4 -2
@@ -965,7 +965,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, err =wait_func (dev, ent);if (err == -ETIMEDOUT ) - goto out_free; + goto out; ds = ent->ts2 - ent->ts1; op =MLX5_GET (mbox_in, in->first.data, opcode);
@@ -1428,6 +1428,7 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced)mlx5_core_err (dev,"Command completion arrived after timeout (entry idx = %d).\n" , ent->idx);free_ent (cmd, ent->idx); +free_cmd (ent); }continue ; }
@@ -1486,7 +1487,8 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced)free_msg (dev, ent->in); err = err ? err : ent->status; -free_cmd (ent); +if (!forced) +free_cmd (ent);callback (err, context); }else {complete (&ent->done);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 21/98 tipc: Fix tipc_sk_reinit handling of -EAGAIN
In reply to Sasha LevinFrom: Bob Peterson <[email protected]>
[ Upstream commit 6c7e983b220f89e03286dc70a41c7ef3a8b409df ]
In 9dbbfb0ab6680c6a85609041011484e6658e7d3c function tipc_sk_reinit had additional logic added to loop in the event that function rhashtable_walk_next() returned -EAGAIN. No worries.
However, if rhashtable_walk_start returns -EAGAIN, it does "continue", and therefore skips the call to rhashtable_walk_stop(). That has the effect of calling rcu_read_lock() without its paired call to rcu_read_unlock(). Since rcu_read_lock() may be nested, the problem may not be apparent for a while, especially since resize events may be rare. But the comments to rhashtable_walk_start() state:
* ...Note that we take the RCU lock in all
* cases including when we return an error. So you must always call
* rhashtable_walk_stop to clean up.
This patch replaces the continue with a goto and label to ensure a matching call to rhashtable_walk_stop().
--- net/tipc/socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/tipc/socket.c +3 -3
@@ -2277,8 +2277,8 @@ void tipc_sk_reinit(struct net *net) do { tsk = ERR_PTR(rhashtable_walk_start(&iter)); - if (tsk) - continue; + if (IS_ERR(tsk)) + goto walk_stop; while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) { spin_lock_bh(&tsk->sk.sk_lock.slock);
@@ -2287,7 +2287,7 @@ void tipc_sk_reinit(struct net *net)msg_set_orignode (msg, tn->own_addr);spin_unlock_bh (&tsk->sk.sk_lock.slock); } - +walk_stop:rhashtable_walk_stop (&iter); }while (tsk ==ERR_PTR (-EAGAIN )); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 22/98 tipc: fix a race condition of releasing subscriber object
In reply to Sasha LevinFrom: Ying Xue <[email protected]>
[ Upstream commit fd849b7c41f0fabfe783d0691a63c5518e8ebc99 ]
No matter whether a request is inserted into workqueue as a work item to cancel a subscription or to delete a subscription's subscriber asynchronously, the work items may be executed in different workers. As a result, it doesn't mean that one request which is raised prior to another request is definitely handled before the latter. By contrast, if the latter request is executed before the former request, below error may happen:
[ 656.183644] BUG: spinlock bad magic on CPU#0, kworker/u8:0/12117 [ 656.184487] general protection fault: 0000 [#1] SMP [ 656.185160] Modules linked in: tipc ip6_udp_tunnel udp_tunnel 9pnet_virtio 9p 9pnet virtio_net virtio_pci virtio_ring virtio [last unloaded: ip6_udp_tunnel] [ 656.187003] CPU: 0 PID: 12117 Comm: kworker/u8:0 Not tainted 4.11.0-rc7+ #6 [ 656.187920] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 656.188690] Workqueue: tipc_rcv tipc_recv_work [tipc] [ 656.189371] task: ffff88003f5cec40 task.stack: ffffc90004448000 [ 656.190157] RIP: 0010:spin_bug+0xdd/0xf0 [ 656.190678] RSP: 0018:ffffc9000444bcb8 EFLAGS: 00010202 [ 656.191375] RAX: 0000000000000034 RBX: ffff88003f8d1388 RCX: 0000000000000000 [ 656.192321] RDX: ffff88003ba13708 RSI: ffff88003ba0cd08 RDI: ffff88003ba0cd08 [ 656.193265] RBP: ffffc9000444bcd0 R08: 0000000000000030 R09: 000000006b6b6b6b [ 656.194208] R10: ffff8800bde3e000 R11: 00000000000001b4 R12: 6b6b6b6b6b6b6b6b [ 656.195157] R13: ffffffff81a3ca64 R14: ffff88003f8d1388 R15: ffff88003f8d13a0 [ 656.196101] FS: 0000000000000000(0000) GS:ffff88003ba00000(0000) knlGS:0000000000000000 [ 656.197172] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 656.197935] CR2: 00007f0b3d2e6000 CR3: 000000003ef9e000 CR4: 00000000000006f0 [ 656.198873] Call Trace: [ 656.199210] do_raw_spin_lock+0x66/0xa0 [ 656.199735] _raw_spin_lock_bh+0x19/0x20 [ 656.200258] tipc_subscrb_subscrp_delete+0x28/0xf0 [tipc] [ 656.200990] tipc_subscrb_rcv_cb+0x45/0x260 [tipc] [ 656.201632] tipc_receive_from_sock+0xaf/0x100 [tipc] [ 656.202299] tipc_recv_work+0x2b/0x60 [tipc] [ 656.202872] process_one_work+0x157/0x420 [ 656.203404] worker_thread+0x69/0x4c0 [ 656.203898] kthread+0x138/0x170 [ 656.204328] ? process_one_work+0x420/0x420 [ 656.204889] ? kthread_create_on_node+0x40/0x40 [ 656.205527] ret_from_fork+0x29/0x40 [ 656.206012] Code: 48 8b 0c 25 00 c5 00 00 48 c7 c7 f0 24 a3 81 48 81 c1 f0 05 00 00 65 8b 15 61 ef f5 7e e8 9a 4c 09 00 4d 85 e4 44 8b 4b 08 74 92 <45> 8b 84 24 40 04 00 00 49 8d 8c 24 f0 05 00 00 eb 8d 90 0f 1f [ 656.208504] RIP: spin_bug+0xdd/0xf0 RSP: ffffc9000444bcb8 [ 656.209798] ---[ end trace e2a800e6eb0770be ]---
In above scenario, the request of deleting subscriber was performed earlier than the request of canceling a subscription although the latter was issued before the former, which means tipc_subscrb_delete() was called before tipc_subscrp_cancel(). As a result, when tipc_subscrb_subscrp_delete() called by tipc_subscrp_cancel() was executed to cancel a subscription, the subscription's subscriber refcnt had been decreased to 1. After tipc_subscrp_delete() where the subscriber was freed because its refcnt was decremented to zero, but the subscriber's lock had to be released, as a consequence, panic happened.
By contrast, if we increase subscriber's refcnt before tipc_subscrb_subscrp_delete() is called in tipc_subscrp_cancel(), the panic issue can be avoided.
--- net/tipc/subscr.c | 2 ++ 1 file changed, 2 insertions(+)
net/tipc/subscr.c +2 -0
@@ -256,7 +256,9 @@ static void tipc_subscrp_delete(struct tipc_subscription *sub)static void tipc_subscrp_cancel (struct tipc_subscr *s,struct tipc_subscriber *subscriber) { +tipc_subscrb_get (subscriber);tipc_subscrb_subscrp_delete (subscriber, s); +tipc_subscrb_put (subscriber); } static struct tipc_subscription *tipc_subscrp_create(struct net *net,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 23/98 bnxt_en: Don't use rtnl lock to protect link change logic in workqueue.
In reply to Sasha LevinFrom: Michael Chan <[email protected]>
[ Upstream commit e2dc9b6e38fa3919e63d6d7905da70ca41cbf908 ]
As a further improvement to the PF/VF link change logic, use a private mutex instead of the rtnl lock to protect link change logic. With the new mutex, we don't have to take the rtnl lock in the workqueue when we have to handle link related functions. If the VF and PF drivers are running on the same host and both take the rtnl lock and one is waiting for the other, it will cause timeout. This patch fixes these timeouts.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 25 ++++++++++--------- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 4 +++ .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 4 +++ 3 files changed, 21 insertions(+), 12 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +13 -12
@@ -5580,7 +5580,9 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) }if (link_re_init) { +mutex_lock (&bp->link_lock); rc =bnxt_update_phy_setting (bp); +mutex_unlock (&bp->link_lock);if (rc)netdev_warn (bp->dev,"failed to update phy settings\n" ); }
@@ -6230,30 +6232,28 @@ static void bnxt_sp_task(struct work_struct *work)if (test_and_clear_bit (BNXT_PERIODIC_STATS_SP_EVENT , &bp->sp_event))bnxt_hwrm_port_qstats (bp); -/* These functions below will clear BNXT_STATE_IN_SP_TASK. They -* must be the last functions to be called before exiting. -*/ if (test_and_clear_bit (BNXT_LINK_CHNG_SP_EVENT , &bp->sp_event)) { -int rc =0 ; +int rc; +mutex_lock (&bp->link_lock);if (test_and_clear_bit (BNXT_LINK_SPEED_CHNG_SP_EVENT , &bp->sp_event))bnxt_hwrm_phy_qcaps (bp); -bnxt_rtnl_lock_sp (bp); -if (test_bit (BNXT_STATE_OPEN , &bp->state)) - rc =bnxt_update_link (bp, true); -bnxt_rtnl_unlock_sp (bp); + rc =bnxt_update_link (bp, true); +mutex_unlock (&bp->link_lock);if (rc)netdev_err (bp->dev,"SP task can't update link (rc: %x)\n" , rc); }if (test_and_clear_bit (BNXT_HWRM_PORT_MODULE_SP_EVENT , &bp->sp_event)) { -bnxt_rtnl_lock_sp (bp); -if (test_bit (BNXT_STATE_OPEN , &bp->state)) -bnxt_get_port_module_status (bp); -bnxt_rtnl_unlock_sp (bp); +mutex_lock (&bp->link_lock); +bnxt_get_port_module_status (bp); +mutex_unlock (&bp->link_lock); } +/* These functions below will clear BNXT_STATE_IN_SP_TASK. They +* must be the last functions to be called before exiting. +*/ if (test_and_clear_bit (BNXT_RESET_TASK_SP_EVENT , &bp->sp_event))bnxt_reset (bp, false);
@@ -6788,6 +6788,7 @@ static int bnxt_probe_phy(struct bnxt *bp) rc);return rc; } +mutex_init (&bp->link_lock); rc =bnxt_update_link (bp, false);if (rc) {
drivers/net/ethernet/broadcom/bnxt/bnxt.h +4 -0
@@ -1109,6 +1109,10 @@ struct bnxt {unsigned long *ntp_fltr_bmap;int ntp_fltr_count; +/* To protect link related settings during link changes and +* ethtool settings changes. +*/ +struct mutex link_lock;struct bnxt_link_info link_info;struct ethtool_eee eee;u32 lpi_tmr_lo;
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +4 -0
@@ -793,6 +793,7 @@ static int bnxt_get_link_ksettings(struct net_device *dev,u32 ethtool_speed;ethtool_link_ksettings_zero_link_mode (lk_ksettings, supported); +mutex_lock (&bp->link_lock);bnxt_fw_to_ethtool_support_spds (link_info, lk_ksettings);ethtool_link_ksettings_zero_link_mode (lk_ksettings, advertising);
@@ -840,6 +841,7 @@ static int bnxt_get_link_ksettings(struct net_device *dev, base->port =PORT_FIBRE ; } base->phy_address = link_info->phy_addr; +mutex_unlock (&bp->link_lock);return 0 ; }
@@ -926,6 +928,7 @@ static int bnxt_set_link_ksettings(struct net_device *dev,if (!BNXT_SINGLE_PF (bp))return -EOPNOTSUPP ; +mutex_lock (&bp->link_lock);if (base->autoneg ==AUTONEG_ENABLE ) {BNXT_ETHTOOL_TO_FW_SPDS (fw_advertising, lk_ksettings, advertising);
@@ -970,6 +973,7 @@ static int bnxt_set_link_ksettings(struct net_device *dev, rc =bnxt_hwrm_set_link_setting (bp, set_pause, false); set_setting_exit: +mutex_unlock (&bp->link_lock);return rc; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 24/98 ath10k: fix NAPI enable/disable symmetry for AHB interface
In reply to Sasha LevinFrom: Mohammed Shafi Shajakhan <[email protected]>
[ Upstream commit a7595a820b07db9ac0d8f479ff62002bdd32a05a ]
Move NAPI enable to 'ath10k_ahb_hif_start' from 'ath10k_ahb_hif_power_up'. This is to maintain the symmetry of calling napi_enable() from ath10k_ahb_hif_start() so that it matches with napi_disable() being called from ath10k_pci_hif_stop().
This change is based on the crash fix from Kalle for PCI interface in commit 1427228d5869 ("ath10k: fix napi crash during rmmod when probe firmware fails").
--- drivers/net/wireless/ath/ath10k/ahb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ath10k/ahb.c +1 -1
@@ -640,6 +640,7 @@ static int ath10k_ahb_hif_start(struct ath10k *ar) {ath10k_dbg (ar,ATH10K_DBG_BOOT ,"boot ahb hif start\n" ); +napi_enable (&ar->napi);ath10k_ce_enable_interrupts (ar);ath10k_pci_enable_legacy_irq (ar);
@@ -692,7 +693,6 @@ static int ath10k_ahb_hif_power_up(struct ath10k *ar)ath10k_err (ar,"could not wake up target CPU: %d\n" , ret); goto err_ce_deinit; } -napi_enable (&ar->napi);return 0 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 25/98 ARM: dts: bcm283x: Reserve first page for firmware
In reply to Sasha LevinFrom: Phil Elwell <[email protected]>
[ Upstream commit b0804ed0cadd7e38d94d2f15cdcc0d9695818856 ]
The Raspberry Pi startup stub files for multi-core BCM283X processors make the secondary CPUs spin until the corresponding mailbox is written. These stubs are loaded at physical address 0x00000xxx (as seen by the ARMs), but this page will be reused by the kernel unless it is explicitly reserved, causing the waiting cores to execute random code.
Use the /memreserve/ Device Tree directive to mark the first page as off-limits to the kernel.
See: https://github.com/raspberrypi/linux/issues/1989
--- arch/arm/boot/dts/bcm283x.dtsi | 5 +++++ 1 file changed, 5 insertions(+)
arch/arm/boot/dts/bcm283x.dtsi +5 -0
@@ -3,6 +3,11 @@ #include <dt-bindings/clock/bcm2835-aux.h> #include <dt-bindings/gpio/gpio.h> +/* firmware-provided startup stubs live here, where the secondary CPUs are + * spinning. + */ +/memreserve/ 0x00000000 0x00001000; + /* This include file covers the common peripherals and configuration between * bcm2835 and bcm2836 implementations, leaving the CPU configuration to * bcm2835.dtsi and bcm2836.dtsi.
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 26/98 btrfs: fiemap: Cache and merge fiemap extent before submit it to user
In reply to Sasha LevinFrom: Qu Wenruo <[email protected]>
[ Upstream commit 4751832da990a927c37526ae67b9226ea01eb99e ]
[BUG]
Cycle mount btrfs can cause fiemap to return different result. Like:
# mount /dev/vdb5 /mnt/btrfs # dd if=/dev/zero bs=16K count=4 oflag=dsync of=/mnt/btrfs/file # xfs_io -c "fiemap -v" /mnt/btrfs/file /mnt/test/file: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..127]: 25088..25215 128 0x1 # umount /mnt/btrfs # mount /dev/vdb5 /mnt/btrfs # xfs_io -c "fiemap -v" /mnt/btrfs/file /mnt/test/file: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..31]: 25088..25119 32 0x0 1: [32..63]: 25120..25151 32 0x0 2: [64..95]: 25152..25183 32 0x0 3: [96..127]: 25184..25215 32 0x1 But after above fiemap, we get correct merged result if we call fiemap again. # xfs_io -c "fiemap -v" /mnt/btrfs/file /mnt/test/file: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..127]: 25088..25215 128 0x1
[REASON]
Btrfs will try to merge extent map when inserting new extent map.
btrfs_fiemap(start=0 len=(u64)-1)
|- extent_fiemap(start=0 len=(u64)-1)
|- get_extent_skip_holes(start=0 len=64k) | |- btrfs_get_extent_fiemap(start=0 len=64k) | |- btrfs_get_extent(start=0 len=64k) | | Found on-disk (ino, EXTENT_DATA, 0) | |- add_extent_mapping() | |- Return (em->start=0, len=16k) | |- fiemap_fill_next_extent(logic=0 phys=X len=16k) | |- get_extent_skip_holes(start=0 len=64k) | |- btrfs_get_extent_fiemap(start=0 len=64k) | |- btrfs_get_extent(start=16k len=48k) | | Found on-disk (ino, EXTENT_DATA, 16k) | |- add_extent_mapping() | | |- try_merge_map() | | Merge with previous em start=0 len=16k | | resulting em start=0 len=32k | |- Return (em->start=0, len=32K) << Merged result |- Stripe off the unrelated range (0~16K) of return em |- fiemap_fill_next_extent(logic=16K phys=X+16K len=16K)
^^^ Causing split fiemap extent.
And since in add_extent_mapping(), em is already merged, in next fiemap() call, we will get merged result.
[FIX]
Here we introduce a new structure, fiemap_cache, which records previous fiemap extent.
And will always try to merge current fiemap_cache result before calling fiemap_fill_next_extent().
Only when we failed to merge current fiemap extent with cached one, we will call fiemap_fill_next_extent() to submit cached one.
So by this method, we can merge all fiemap extents.
It can also be done in fs/ioctl.c, however the problem is if fieinfo->fi_extents_max == 0, we have no space to cache previous fiemap extent.
So I choose to merge it in btrfs.
--- fs/btrfs/extent_io.c | 124 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-)
fs/btrfs/extent_io.c +122 -2
@@ -4377,6 +4377,123 @@ static struct extent_map *get_extent_skip_holes(struct inode *inode,return NULL ; } +/* +* To cache previous fiemap extent +* +* Will be used for merging fiemap extent +*/ +struct fiemap_cache { +u64 offset; +u64 phys; +u64 len; +u32 flags; +bool cached; +}; + +/* +* Helper to submit fiemap extent. +* +* Will try to merge current fiemap extent specified by @offset, @phys, +* @len and @flags with cached one. +* And only when we fails to merge, cached one will be submitted as +* fiemap extent. +* +* Return value is the same as fiemap_fill_next_extent(). +*/ +static int emit_fiemap_extent (struct fiemap_extent_info *fieinfo, +struct fiemap_cache *cache, +u64 offset,u64 phys,u64 len,u32 flags) +{ +int ret =0 ; + +if (!cache->cached) + goto assign; + +/* +* Sanity check, extent_fiemap() should have ensured that new +* fiemap extent won't overlap with cahced one. +* Not recoverable. +* +* NOTE: Physical address can overlap, due to compression +*/ +if (cache->offset + cache->len > offset) { +WARN_ON (1 ); +return -EINVAL ; + } + +/* +* Only merges fiemap extents if +* 1) Their logical addresses are continuous +* +* 2) Their physical addresses are continuous +* So truly compressed (physical size smaller than logical size) +* extents won't get merged with each other +* +* 3) Share same flags except FIEMAP_EXTENT_LAST +* So regular extent won't get merged with prealloc extent +*/ +if (cache->offset + cache->len == offset && + cache->phys + cache->len == phys && + (cache->flags & ~FIEMAP_EXTENT_LAST ) == + (flags & ~FIEMAP_EXTENT_LAST )) { + cache->len += len; + cache->flags |= flags; + goto try_submit_last; + } + +/* Not mergeable, need to submit cached one */ + ret =fiemap_fill_next_extent (fieinfo, cache->offset, cache->phys, + cache->len, cache->flags); + cache->cached = false; +if (ret) +return ret; +assign: + cache->cached = true; + cache->offset = offset; + cache->phys = phys; + cache->len = len; + cache->flags = flags; +try_submit_last: +if (cache->flags &FIEMAP_EXTENT_LAST ) { + ret =fiemap_fill_next_extent (fieinfo, cache->offset, + cache->phys, cache->len, cache->flags); + cache->cached = false; + } +return ret; +} + +/* +* Sanity check for fiemap cache +* +* All fiemap cache should be submitted by emit_fiemap_extent() +* Iteration should be terminated either by last fiemap extent or +* fieinfo->fi_extents_max. +* So no cached fiemap should exist. +*/ +static int check_fiemap_cache (struct btrfs_fs_info *fs_info, +struct fiemap_extent_info *fieinfo, +struct fiemap_cache *cache) +{ +int ret; + +if (!cache->cached) +return 0 ; + +/* Small and recoverbale problem, only to info developer */ +#ifdef CONFIG_BTRFS_DEBUG +WARN_ON (1 ); +#endif +btrfs_warn (fs_info, +"unhandled fiemap cache detected: offset=%llu phys=%llu len=%llu flags=0x%x" , + cache->offset, cache->phys, cache->len, cache->flags); + ret =fiemap_fill_next_extent (fieinfo, cache->offset, cache->phys, + cache->len, cache->flags); + cache->cached = false; +if (ret >0 ) + ret =0 ; +return ret; +} +int extent_fiemap (struct inode *inode,struct fiemap_extent_info *fieinfo,__u64 start,__u64 len,get_extent_t *get_extent) {
@@ -4394,6 +4511,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,struct extent_state *cached_state =NULL ;struct btrfs_path *path;struct btrfs_root *root =BTRFS_I (inode)->root; +struct fiemap_cache cache = {0 };int end =0 ;u64 em_start =0 ;u64 em_len =0 ;
@@ -4573,8 +4691,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, flags |=FIEMAP_EXTENT_LAST ; end =1 ; } - ret =fiemap_fill_next_extent (fieinfo, em_start, disko, - em_len, flags); + ret =emit_fiemap_extent (fieinfo, &cache, em_start, disko, + em_len, flags);if (ret) {if (ret ==1 ) ret =0 ;
@@ -4582,6 +4700,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, } } out_free: +if (!ret) + ret =check_fiemap_cache (root->fs_info, fieinfo, &cache);free_extent_map (em); out:btrfs_free_path (path);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 27/98 ata: sata_rcar: Handle return value of clk_prepare_enable
In reply to Sasha LevinFrom: Arvind Yadav <[email protected]>
[ Upstream commit 5dc63fdcc09f47fb226b8bc7d83a61feb787d817 ]
Here, Clock enable can failed. So adding an error check for clk_prepare_enable.
tj: minor style updates
--- drivers/ata/sata_rcar.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/ata/sata_rcar.c +12 -3
@@ -890,7 +890,10 @@ static int sata_rcar_probe(struct platform_device *pdev)dev_err (&pdev->dev,"failed to get access to sata clock\n" );return PTR_ERR (priv->clk); } -clk_prepare_enable (priv->clk); + + ret =clk_prepare_enable (priv->clk); +if (ret) +return ret; host =ata_host_alloc (&pdev->dev,1 );if (!host) {
@@ -970,8 +973,11 @@ static int sata_rcar_resume(struct device *dev)struct ata_host *host =dev_get_drvdata (dev);struct sata_rcar_priv *priv = host->private_data;void __iomem *base = priv->base; +int ret; -clk_prepare_enable (priv->clk); + ret =clk_prepare_enable (priv->clk); +if (ret) +return ret;/* ack and mask */ iowrite32 (0 , base +SATAINTSTAT_REG );
@@ -988,8 +994,11 @@ static int sata_rcar_restore(struct device *dev) {struct ata_host *host =dev_get_drvdata (dev);struct sata_rcar_priv *priv = host->private_data; +int ret; -clk_prepare_enable (priv->clk); + ret =clk_prepare_enable (priv->clk); +if (ret) +return ret;sata_rcar_setup_port (host);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 28/98 reset: hi6220: Set module license so that it can be loaded
In reply to Sasha LevinFrom: Jeremy Linton <[email protected]>
[ Upstream commit 4497a224f759cd8350e07382307b55f870ef0df2 ]
The hi6220_reset driver can be built as a standalone module yet it cannot be loaded because it depends on GPL exported symbols.
Lets set the module license so that the module loads, and things like the on-board kirin drm starts working.
--- drivers/reset/hisilicon/hi6220_reset.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/reset/hisilicon/hi6220_reset.c +2 -0
@@ -155,3 +155,5 @@ static int __init hi6220_reset_init(void) }postcore_initcall (hi6220_reset_init); + +MODULE_LICENSE ("GPL v2" );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 29/98 ASoC: Intel: Skylake: Fix to parse consecutive string tkns in manifest
In reply to Sasha LevinFrom: Shreyas NC <[email protected]>
[ Upstream commit 0a716776914ed9d7ca90b48041e6767693bfb672 ]
Element size in the manifest should be updated for each token, so that the loop can parse all the string elements in the manifest. This was not happening when more than two string elements appear consecutively, as it is not updated with correct string element size. Fixed with this patch.
--- sound/soc/intel/skylake/skl-topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/intel/skylake/skl-topology.c +1 -1
@@ -2325,7 +2325,7 @@ static int skl_tplg_get_manifest_tkn(struct device *dev,if (ret <0 )return ret; - tkn_count += ret; + tkn_count = ret; tuple_size += tkn_count *sizeof (struct snd_soc_tplg_vendor_string_elem );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 30/98 arch/sparc: increase CONFIG_NODES_SHIFT on SPARC64 to 5
In reply to Sasha LevinFrom: Jane Chu <[email protected]>
[ Upstream commit 7485af89a6fd48f7e6fab2505d2364d1817723e6 ]
SPARC M6-32 platform has (2^5) NUMA nodes, so need to bump up the CONFIG_NODES_SHIFT to 5.
Orabug: 25577754
--- arch/sparc/Kconfig | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/sparc/Kconfig +6 -2
@@ -290,9 +290,13 @@ config NUMA depends on SPARC64 && SMP config NODES_SHIFT - int - default "4" + int "Maximum NUMA Nodes (as a power of 2)" + range 4 5 if SPARC64 + default "5" depends on NEED_MULTIPLE_NODES + help + Specify the maximum number of NUMA Nodes available on the target + system. Increases memory reserved to accommodate various tables. # Some NUMA nodes have memory ranges that span # other nodes. Even though a pfn is valid and
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 31/98 mac80211: fix TX aggregation start/stop callback race
In reply to Sasha LevinFrom: Johannes Berg <[email protected]>
[ Upstream commit 7a7c0a6438b8e7636d5a22e572892cc234f68297 ]
When starting or stopping an aggregation session, one of the steps is that the driver calls back to mac80211 that the start/stop can proceed. This is handled by queueing up a fake SKB and processing it from the normal iface/sdata work. Since this isn't flushed when disassociating, the following race is possible:
* associate
* start aggregation session
* driver callback
* disassociate
* associate again to the same AP
* callback processing runs, leading to a WARN_ON() that the TID hadn't requested aggregation
If the second association isn't to the same AP, there would only be a message printed ("Could not find station: <addr>"), but the same race could happen.
Fix this by not going the whole detour with a fake SKB etc. but simply looking up the aggregation session in the driver callback, marking it with a START_CB/STOP_CB bit and then scheduling the regular aggregation work that will now process these bits as well. This also simplifies the code and gets rid of the whole problem with allocation failures of said skb, which could have left the session in limbo.
--- net/mac80211/agg-tx.c | 128 +++++++++++++++---------------------- net/mac80211/ht.c | 16 +++-- net/mac80211/ieee80211_i.h | 14 ++-- net/mac80211/iface.c | 11 +--- net/mac80211/sta_info.h | 2 + 5 files changed, 71 insertions(+), 100 deletions(-)
net/mac80211/agg-tx.c +52 -76
@@ -7,7 +7,7 @@* Copyright 2006-2007 Jiri Benc <[email protected]> * Copyright 2007, Michael Wu <[email protected]> * Copyright 2007-2010, Intel Corporation -* Copyright(c) 2015 Intel Deutschland GmbH +* Copyright(c) 2015-2017 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as
@@ -741,46 +741,43 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,ieee80211_agg_start_txq (sta, tid, true); } -void ieee80211_start_tx_ba_cb (struct ieee80211_vif *vif,u8 *ra,u16 tid) +void ieee80211_start_tx_ba_cb (struct sta_info *sta,int tid, +struct tid_ampdu_tx *tid_tx) { -struct ieee80211_sub_if_data *sdata =vif_to_sdata (vif); +struct ieee80211_sub_if_data *sdata = sta->sdata;struct ieee80211_local *local = sdata->local; -struct sta_info *sta; -struct tid_ampdu_tx *tid_tx; -trace_api_start_tx_ba_cb (sdata, ra, tid); +if (WARN_ON (test_and_set_bit (HT_AGG_STATE_DRV_READY , &tid_tx->state))) +return ; + +if (test_bit (HT_AGG_STATE_RESPONSE_RECEIVED , &tid_tx->state)) +ieee80211_agg_tx_operational (local, sta, tid); +} + +static struct tid_ampdu_tx * +ieee80211_lookup_tid_tx (struct ieee80211_sub_if_data *sdata, +const u8 *ra,u16 tid,struct sta_info **sta) +{ +struct tid_ampdu_tx *tid_tx;if (tid >=IEEE80211_NUM_TIDS ) {ht_dbg (sdata,"Bad TID value: tid = %d (>= %d)\n" , tid,IEEE80211_NUM_TIDS ); -return ; +return NULL ; } -mutex_lock (&local->sta_mtx); - sta =sta_info_get_bss (sdata, ra); -if (!sta) { -mutex_unlock (&local->sta_mtx); + *sta =sta_info_get_bss (sdata, ra); +if (!*sta) {ht_dbg (sdata,"Could not find station: %pM\n" , ra); -return ; +return NULL ; } -mutex_lock (&sta->ampdu_mlme.mtx); - tid_tx =rcu_dereference_protected_tid_tx (sta, tid); + tid_tx =rcu_dereference ((*sta)->ampdu_mlme.tid_tx[tid]); -if (WARN_ON (!tid_tx)) { +if (WARN_ON (!tid_tx))ht_dbg (sdata,"addBA was not requested!\n" ); - goto unlock; - } -if (WARN_ON (test_and_set_bit (HT_AGG_STATE_DRV_READY , &tid_tx->state))) - goto unlock; - -if (test_bit (HT_AGG_STATE_RESPONSE_RECEIVED , &tid_tx->state)) -ieee80211_agg_tx_operational (local, sta, tid); - - unlock: -mutex_unlock (&sta->ampdu_mlme.mtx); -mutex_unlock (&local->sta_mtx); +return tid_tx; } void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
@@ -788,19 +785,20 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, {struct ieee80211_sub_if_data *sdata =vif_to_sdata (vif);struct ieee80211_local *local = sdata->local; -struct ieee80211_ra_tid *ra_tid; -struct sk_buff *skb =dev_alloc_skb (0 ); +struct sta_info *sta; +struct tid_ampdu_tx *tid_tx; -if (unlikely (!skb)) -return ; +trace_api_start_tx_ba_cb (sdata, ra, tid); - ra_tid = (struct ieee80211_ra_tid *) &skb->cb; -memcpy (&ra_tid->ra, ra,ETH_ALEN ); - ra_tid->tid = tid; +rcu_read_lock (); + tid_tx =ieee80211_lookup_tid_tx (sdata, ra, tid, &sta); +if (!tid_tx) + goto out; - skb->pkt_type =IEEE80211_SDATA_QUEUE_AGG_START ; -skb_queue_tail (&sdata->skb_queue, skb); -ieee80211_queue_work (&local->hw, &sdata->work); +set_bit (HT_AGG_STATE_START_CB , &tid_tx->state); +ieee80211_queue_work (&local->hw, &sta->ampdu_mlme.work); + out: +rcu_read_unlock (); }EXPORT_SYMBOL (ieee80211_start_tx_ba_cb_irqsafe);
@@ -860,37 +858,18 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) }EXPORT_SYMBOL (ieee80211_stop_tx_ba_session); -void ieee80211_stop_tx_ba_cb (struct ieee80211_vif *vif,u8 *ra,u8 tid) +void ieee80211_stop_tx_ba_cb (struct sta_info *sta,int tid, +struct tid_ampdu_tx *tid_tx) { -struct ieee80211_sub_if_data *sdata =vif_to_sdata (vif); -struct ieee80211_local *local = sdata->local; -struct sta_info *sta; -struct tid_ampdu_tx *tid_tx; +struct ieee80211_sub_if_data *sdata = sta->sdata;bool send_delba = false; -trace_api_stop_tx_ba_cb (sdata, ra, tid); - -if (tid >=IEEE80211_NUM_TIDS ) { -ht_dbg (sdata,"Bad TID value: tid = %d (>= %d)\n" , - tid,IEEE80211_NUM_TIDS ); -return ; - } - -ht_dbg (sdata,"Stopping Tx BA session for %pM tid %d\n" , ra, tid); - -mutex_lock (&local->sta_mtx); - - sta =sta_info_get_bss (sdata, ra); -if (!sta) { -ht_dbg (sdata,"Could not find station: %pM\n" , ra); - goto unlock; - } +ht_dbg (sdata,"Stopping Tx BA session for %pM tid %d\n" , + sta->sta.addr, tid); -mutex_lock (&sta->ampdu_mlme.mtx);spin_lock_bh (&sta->lock); - tid_tx =rcu_dereference_protected_tid_tx (sta, tid); -if (!tid_tx || !test_bit (HT_AGG_STATE_STOPPING , &tid_tx->state)) { +if (!test_bit (HT_AGG_STATE_STOPPING , &tid_tx->state)) {ht_dbg (sdata,"unexpected callback to A-MPDU stop for %pM tid %d\n" , sta->sta.addr, tid);
@@ -906,12 +885,8 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)spin_unlock_bh (&sta->lock);if (send_delba) -ieee80211_send_delba (sdata, ra, tid, +ieee80211_send_delba (sdata, sta->sta.addr, tid,WLAN_BACK_INITIATOR ,WLAN_REASON_QSTA_NOT_USE ); - -mutex_unlock (&sta->ampdu_mlme.mtx); - unlock: -mutex_unlock (&local->sta_mtx); } void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
@@ -919,19 +894,20 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, {struct ieee80211_sub_if_data *sdata =vif_to_sdata (vif);struct ieee80211_local *local = sdata->local; -struct ieee80211_ra_tid *ra_tid; -struct sk_buff *skb =dev_alloc_skb (0 ); +struct sta_info *sta; +struct tid_ampdu_tx *tid_tx; -if (unlikely (!skb)) -return ; +trace_api_stop_tx_ba_cb (sdata, ra, tid); - ra_tid = (struct ieee80211_ra_tid *) &skb->cb; -memcpy (&ra_tid->ra, ra,ETH_ALEN ); - ra_tid->tid = tid; +rcu_read_lock (); + tid_tx =ieee80211_lookup_tid_tx (sdata, ra, tid, &sta); +if (!tid_tx) + goto out; - skb->pkt_type =IEEE80211_SDATA_QUEUE_AGG_STOP ; -skb_queue_tail (&sdata->skb_queue, skb); -ieee80211_queue_work (&local->hw, &sdata->work); +set_bit (HT_AGG_STATE_STOP_CB , &tid_tx->state); +ieee80211_queue_work (&local->hw, &sta->ampdu_mlme.work); + out: +rcu_read_unlock (); }EXPORT_SYMBOL (ieee80211_stop_tx_ba_cb_irqsafe);
net/mac80211/ht.c +12 -4
@@ -7,6 +7,7 @@* Copyright 2006-2007 Jiri Benc <[email protected]> * Copyright 2007, Michael Wu <[email protected]> * Copyright 2007-2010, Intel Corporation +* Copyright 2017 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as
@@ -289,8 +290,6 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, {int i; -cancel_work_sync (&sta->ampdu_mlme.work); -for (i =0 ; i <IEEE80211_NUM_TIDS ; i++) {__ieee80211_stop_tx_ba_session (sta, i, reason); __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
@@ -298,6 +297,9 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, reason !=AGG_STOP_DESTROY_STA && reason != AGG_STOP_PEER_REQUEST); } + +/* stopping might queue the work again - so cancel only afterwards */ +cancel_work_sync (&sta->ampdu_mlme.work); }void ieee80211_ba_session_work (struct work_struct *work)
@@ -352,10 +354,16 @@ void ieee80211_ba_session_work(struct work_struct *work)spin_unlock_bh (&sta->lock); tid_tx =rcu_dereference_protected_tid_tx (sta, tid); -if (tid_tx &&test_and_clear_bit (HT_AGG_STATE_WANT_STOP , - &tid_tx->state)) +if (!tid_tx) +continue ; + +if (test_and_clear_bit (HT_AGG_STATE_START_CB , &tid_tx->state)) +ieee80211_start_tx_ba_cb (sta, tid, tid_tx); +if (test_and_clear_bit (HT_AGG_STATE_WANT_STOP , &tid_tx->state))___ieee80211_stop_tx_ba_session (sta, tid,AGG_STOP_LOCAL_REQUEST ); +if (test_and_clear_bit (HT_AGG_STATE_STOP_CB , &tid_tx->state)) +ieee80211_stop_tx_ba_cb (sta, tid, tid_tx); }mutex_unlock (&sta->ampdu_mlme.mtx); }
net/mac80211/ieee80211_i.h +4 -10
@@ -1026,8 +1026,6 @@ struct ieee80211_rx_agg {enum sdata_queue_type {IEEE80211_SDATA_QUEUE_TYPE_FRAME =0 , -IEEE80211_SDATA_QUEUE_AGG_START =1 , -IEEE80211_SDATA_QUEUE_AGG_STOP =2 ,IEEE80211_SDATA_QUEUE_RX_AGG_START =3 ,IEEE80211_SDATA_QUEUE_RX_AGG_STOP =4 , };
@@ -1416,12 +1414,6 @@ ieee80211_get_sband(struct ieee80211_sub_if_data *sdata)return local->hw.wiphy->bands[band]; } -/* this struct represents 802.11n's RA/TID combination */ -struct ieee80211_ra_tid { -u8 ra[ETH_ALEN ]; -u16 tid; -}; -/* this struct holds the value parsing from channel switch IE */ struct ieee80211_csa_ie {struct cfg80211_chan_def chandef;
@@ -1765,8 +1757,10 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, enum ieee80211_agg_stop_reason reason);int ___ieee80211_stop_tx_ba_session (struct sta_info *sta,u16 tid,enum ieee80211_agg_stop_reason reason); -void ieee80211_start_tx_ba_cb (struct ieee80211_vif *vif,u8 *ra,u16 tid); -void ieee80211_stop_tx_ba_cb (struct ieee80211_vif *vif,u8 *ra,u8 tid); +void ieee80211_start_tx_ba_cb (struct sta_info *sta,int tid, +struct tid_ampdu_tx *tid_tx); +void ieee80211_stop_tx_ba_cb (struct sta_info *sta,int tid, +struct tid_ampdu_tx *tid_tx);void ieee80211_ba_session_work (struct work_struct *work);void ieee80211_tx_ba_session_handle_start (struct sta_info *sta,int tid);void ieee80211_release_reorder_timeout (struct sta_info *sta,int tid);
net/mac80211/iface.c +1 -10
@@ -1248,7 +1248,6 @@ static void ieee80211_iface_work(struct work_struct *work)struct ieee80211_local *local = sdata->local;struct sk_buff *skb;struct sta_info *sta; -struct ieee80211_ra_tid *ra_tid;struct ieee80211_rx_agg *rx_agg;if (!ieee80211_sdata_running (sdata))
@@ -1264,15 +1263,7 @@ static void ieee80211_iface_work(struct work_struct *work)while ((skb =skb_dequeue (&sdata->skb_queue))) {struct ieee80211_mgmt *mgmt = (void *)skb->data; -if (skb->pkt_type ==IEEE80211_SDATA_QUEUE_AGG_START ) { - ra_tid = (void *)&skb->cb; -ieee80211_start_tx_ba_cb (&sdata->vif, ra_tid->ra, - ra_tid->tid); - }else if (skb->pkt_type ==IEEE80211_SDATA_QUEUE_AGG_STOP ) { - ra_tid = (void *)&skb->cb; -ieee80211_stop_tx_ba_cb (&sdata->vif, ra_tid->ra, - ra_tid->tid); - }else if (skb->pkt_type ==IEEE80211_SDATA_QUEUE_RX_AGG_START ) { +if (skb->pkt_type ==IEEE80211_SDATA_QUEUE_RX_AGG_START ) { rx_agg = (void *)&skb->cb;mutex_lock (&local->sta_mtx); sta =sta_info_get_bss (sdata, rx_agg->addr);
net/mac80211/sta_info.h +2 -0
@@ -115,6 +115,8 @@ enum ieee80211_sta_info_flags {#define HT_AGG_STATE_STOPPING 3#define HT_AGG_STATE_WANT_START 4#define HT_AGG_STATE_WANT_STOP 5 +#define HT_AGG_STATE_START_CB 6 +#define HT_AGG_STATE_STOP_CB 7enum ieee80211_agg_stop_reason {AGG_STOP_DECLINED ,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 32/98 libata: fix error checking in in ata_parse_force_one()
In reply to Sasha LevinFrom: Tejun Heo <[email protected]>
[ Upstream commit f7cf69ae171592d133c69b9adaa5de7cfb6038ea ]
ata_parse_force_one() was incorrectly comparing @p to @endp when it should have been comparing @id. The only consequence is that it may end up using an invalid port number in "libata.force" module param instead of rejecting it.
--- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/libata-core.c +1 -1
@@ -6781,7 +6781,7 @@ static int __init ata_parse_force_one(char **cur, } force_ent->port =simple_strtoul (id, &endp,10 ); -if (p == endp || *endp !='\0' ) { +if (id == endp || *endp !='\0' ) { *reason ="invalid port/link" ;return -EINVAL ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 33/98 ARM: dts: imx6ul-14x14-evk: Add ksz8081 phy properties
In reply to Sasha LevinFrom: Leonard Crestez <[email protected]>
[ Upstream commit e6f4292ae0a1e73fae26ced57de13a48f71ad1fa ]
Right now mach-imx6ul registers a fixup for the ksz8081 phy. The same register values can be set through the micrel phy driver by using dts properties.
This seems preferable and allows cleanly fixing suspend/resume.
--- arch/arm/boot/dts/imx6ul-14x14-evk.dts | 6 ++++++ 1 file changed, 6 insertions(+)
arch/arm/boot/dts/imx6ul-14x14-evk.dts +6 -0
@@ -125,10 +125,16 @@ ethphy0: ethernet-phy@2 { reg = <2>; + micrel,led-mode = <1>; + clocks = <&clks IMX6UL_CLK_ENET_REF>; + clock-names = "rmii-ref"; }; ethphy1: ethernet-phy@1 { reg = <1>; + micrel,led-mode = <1>; + clocks = <&clks IMX6UL_CLK_ENET2_REF>; + clock-names = "rmii-ref"; }; }; };
Signature · 1 line
2.17.1
Re: [PATCH AUTOSEL 4.9 33/98] ARM: dts: imx6ul-14x14-evk: Add ksz8081 phy properties
Quoted 8 lines · Sasha Levin
From: Leonard Crestez <[email protected]>
[ Upstream commit
e6f4292ae0a1e73fae26ced57de13a48f71ad1fa]Right now mach-imx6ul registers a fixup for the ksz8081 phy. The same register values can be set through the micrel phy driver by using dts properties.
Quoted 7 lines
This seems preferable and allows cleanly fixing suspend/resume.
Signed-off-by Leonard Crestez <[email protected]>Reviewed-by Fabio Estevam <[email protected]>Reviewed-by Florian Fainelli <[email protected]>Signed-off-by David S. Miller <[email protected]>Signed-off-by Sasha Levin <[email protected]>
This patch only fixes suspend on 6ul evk in combination with 79e498a9c7da ("net: phy: micrel: Restore led_mode and clk_sel on resume"). It is otherwise not very useful to backport just the DT patch.
That patch was earlier backported but then reverted from 4.9 because it unexpectedly caused issues when combined with other phy patches applied out-of-order. It seems a correct fix was eventually made (by backporting bfe72442578b) and 79e498a9c7da could now be restored:
https://lkml.org/lkml/2018/7/11/972
I'm not sure fixing nfsroot suspend/resume on dev boards meets the criteria for linux-stable, especially since it already caused trouble once. In general I'd class "fixing things that never worked before" as not particularly suitable for backporting.
--
Regards,
Leonard
Sasha Levin
maintainerRe: [PATCH AUTOSEL 4.9 33/98] ARM: dts: imx6ul-14x14-evk: Add ksz8081 phy properties
Quoted 26 lines · Leonard Crestez
Quoted 8 lines · Sasha Levin
From: Leonard Crestez <[email protected]>
[ Upstream commit
e6f4292ae0a1e73fae26ced57de13a48f71ad1fa]Right now mach-imx6ul registers a fixup for the ksz8081 phy. The same register values can be set through the micrel phy driver by using dts properties.
Quoted 7 lines
This seems preferable and allows cleanly fixing suspend/resume.
Signed-off-by Leonard Crestez <[email protected]>Reviewed-by Fabio Estevam <[email protected]>Reviewed-by Florian Fainelli <[email protected]>Signed-off-by David S. Miller <[email protected]>Signed-off-by Sasha Levin <[email protected]>This patch only fixes suspend on 6ul evk in combination with
79e498a9c7da("net: phy: micrel: Restoreled_modeandclk_selon resume"). It is otherwise not very useful to backport just the DT patch.That patch was earlier backported but then reverted from 4.9 because it unexpectedly caused issues when combined with other phy patches applied out-of-order. It seems a correct fix was eventually made (by backporting
bfe72442578b) and79e498a9c7dacould now be restored:
Quoted 6 lines
https://lkml.org/lkml/2018/7/11/972I'm not sure fixing nfsroot suspend/resume on dev boards meets the criteria for linux-stable, especially since it already caused trouble once. In general I'd class "fixing things that never worked before" as not particularly suitable for backporting.
Thank you for looking into this, I'll drop the patch.
--
Thanks,
Sasha
Sasha Levin
maintainerPATCH 34/98 net: ethernet: stmmac: Fix altr_tse_pcs SGMII Initialization
In reply to Sasha LevinFrom: Thor Thayer <[email protected]>
[ Upstream commit 77032732d0e89b83c3bca75b857a1f63e9efb44b ]
Fix NETDEV WATCHDOG timeout on startup by adding missing register writes that properly setup SGMII.
--- drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c +5 -1
@@ -37,6 +37,7 @@#define TSE_PCS_CONTROL_AN_EN_MASK BIT(12)#define TSE_PCS_CONTROL_REG 0x00#define TSE_PCS_CONTROL_RESTART_AN_MASK BIT(9) +#define TSE_PCS_CTRL_AUTONEG_SGMII 0x1140#define TSE_PCS_IF_MODE_REG 0x28#define TSE_PCS_LINK_TIMER_0_REG 0x24#define TSE_PCS_LINK_TIMER_1_REG 0x26
@@ -65,6 +66,7 @@#define TSE_PCS_SW_RESET_TIMEOUT 100#define TSE_PCS_USE_SGMII_AN_MASK BIT(1)#define TSE_PCS_USE_SGMII_ENA BIT(0) +#define TSE_PCS_IF_USE_SGMII 0x03#define SGMII_ADAPTER_CTRL_REG 0x00#define SGMII_ADAPTER_DISABLE 0x0001
@@ -101,7 +103,9 @@ int tse_pcs_init(void __iomem *base, struct tse_pcs *pcs) {int ret =0 ; -writew (TSE_PCS_USE_SGMII_ENA , base +TSE_PCS_IF_MODE_REG ); +writew (TSE_PCS_IF_USE_SGMII , base +TSE_PCS_IF_MODE_REG ); + +writew (TSE_PCS_CTRL_AUTONEG_SGMII , base +TSE_PCS_CONTROL_REG );writew (TSE_PCS_SGMII_LINK_TIMER_0 , base +TSE_PCS_LINK_TIMER_0_REG );writew (TSE_PCS_SGMII_LINK_TIMER_1 , base +TSE_PCS_LINK_TIMER_1_REG );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 35/98 qlcnic: Fix tunnel offload for 82xx adapters
In reply to Sasha LevinFrom: "Chopra, Manish" <[email protected]>
[ Upstream commit 4bd7ef0b033721b659b9357057e76d1ced95c1da ]
Qlogic's 82xx series adapter doesn't support tunnel offloads, driver incorrectly assumes that it is supported and causes firmware hang while running tunnel IO.
This patch fixes this by not advertising tunnel offloads for 82xx adapters.
--- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 26 +++++++++++++++++-- .../ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 2 ++ .../net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 ++ .../qlogic/qlcnic/qlcnic_sriov_common.c | 2 ++ 4 files changed, 30 insertions(+), 2 deletions(-)
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +24 -2
@@ -1825,22 +1825,44 @@ struct qlcnic_hardware_ops {u32 (*get_cap_size)(void *,int );void (*set_sys_info)(void *,int ,u32 );void (*store_cap_mask)(void *,u32 ); +bool (*encap_rx_offload) (struct qlcnic_adapter *adapter); +bool (*encap_tx_offload) (struct qlcnic_adapter *adapter); };extern struct qlcnic_nic_template qlcnic_vf_ops; -static inline bool qlcnic_encap_tx_offload (struct qlcnic_adapter *adapter) +static inline bool qlcnic_83xx_encap_tx_offload (struct qlcnic_adapter *adapter) {return adapter->ahw->extra_capability[0 ] &QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD ; } -static inline bool qlcnic_encap_rx_offload (struct qlcnic_adapter *adapter) +static inline bool qlcnic_83xx_encap_rx_offload (struct qlcnic_adapter *adapter) {return adapter->ahw->extra_capability[0 ] &QLCNIC_83XX_FW_CAPAB_ENCAP_RX_OFFLOAD ; } +static inline bool qlcnic_82xx_encap_tx_offload (struct qlcnic_adapter *adapter) +{ +return false; +} + +static inline bool qlcnic_82xx_encap_rx_offload (struct qlcnic_adapter *adapter) +{ +return false; +} + +static inline bool qlcnic_encap_rx_offload (struct qlcnic_adapter *adapter) +{ +return adapter->ahw->hw_ops->encap_rx_offload (adapter); +} + +static inline bool qlcnic_encap_tx_offload (struct qlcnic_adapter *adapter) +{ +return adapter->ahw->hw_ops->encap_tx_offload (adapter); +} +static inline int qlcnic_start_firmware (struct qlcnic_adapter *adapter) {return adapter->nic_ops->start_firmware (adapter);
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +2 -0
@@ -242,6 +242,8 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = { .get_cap_size = qlcnic_83xx_get_cap_size, .set_sys_info = qlcnic_83xx_set_sys_info, .store_cap_mask = qlcnic_83xx_store_cap_mask, + .encap_rx_offload = qlcnic_83xx_encap_rx_offload, + .encap_tx_offload = qlcnic_83xx_encap_tx_offload, };static struct qlcnic_nic_template qlcnic_83xx_ops = {
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +2 -0
@@ -632,6 +632,8 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = { .get_cap_size = qlcnic_82xx_get_cap_size, .set_sys_info = qlcnic_82xx_set_sys_info, .store_cap_mask = qlcnic_82xx_store_cap_mask, + .encap_rx_offload = qlcnic_82xx_encap_rx_offload, + .encap_tx_offload = qlcnic_82xx_encap_tx_offload, };static int qlcnic_check_multi_tx_capability (struct qlcnic_adapter *adapter)
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +2 -0
@@ -77,6 +77,8 @@ static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = { .free_mac_list = qlcnic_sriov_vf_free_mac_list, .enable_sds_intr = qlcnic_83xx_enable_sds_intr, .disable_sds_intr = qlcnic_83xx_disable_sds_intr, + .encap_rx_offload = qlcnic_83xx_encap_rx_offload, + .encap_tx_offload = qlcnic_83xx_encap_tx_offload, };static struct qlcnic_nic_template qlcnic_sriov_vf_ops = {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 36/98 x86/cpu/cyrix: Add alternative Device ID of Geode GX1 SoC
In reply to Sasha LevinFrom: Christian Sünkenberg <[email protected]>
[ Upstream commit ae1d557d8f30cb097b4d1f2ab04fa294588ee1cf ]
A SoC variant of Geode GX1, notably NSC branded SC1100, seems to report an inverted Device ID in its DIR0 configuration register, specifically 0xb instead of the expected 0x4.
Catch this presumably quirky version so it's properly recognized as GX1 and has its cache switched to write-back mode, which provides a significant performance boost in most workloads.
SC1100's datasheet "Geode™ SC1100 Information Appliance On a Chip", states in section 1.1.7.1 "Device ID" that device identification values are specified in SC1100's device errata. These, however, seem to not have been publicly released.
Wading through a number of boot logs and /proc/cpuinfo dumps found on pastebin and blogs, this patch should mostly be relevant for a number of now admittedly aging Soekris NET4801 and PC Engines WRAP devices, the latter being the platform this issue was discovered on. Performance impact was verified using "openssl speed", with write-back caching scaling throughput between -3% and +41%.
--- arch/x86/kernel/cpu/cyrix.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/kernel/cpu/cyrix.c +1 -0
@@ -253,6 +253,7 @@ static void init_cyrix(struct cpuinfo_x86 *c)break ;case 4 :/* MediaGX/GXm or Geode GXM/GXLV/GX1 */ +case 11 :/* GX1 with inverted Device ID */ #ifdef CONFIG_PCI {u32 vendor, device;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 37/98 ARM: 8677/1: boot/compressed: fix decompressor header layout for v7-M
In reply to Sasha LevinFrom: Ard Biesheuvel <[email protected]>
[ Upstream commit 06a4b6d009a1b74a6ec46c5418b46cc53a79fcb8 ]
As reported by Patrice, the header layout of the decompressor is incorrect when building for v7-M. In this case, the __nop macro resolves to 'mov r0, r0', which is emitted as a narrow encoding, resulting in the header data fields to end up at lower offsets than required.
Given the variety of targets we need to support with the same code, the startup sequence is a bit of a jumble, and uses instructions and macros whose encoding widths cannot be specified (badr), or only exist in a narrow encoding (bx)
So force the use of a wide encoding in __nop, and replace the start sequence with a simple jump to the label marking the start of code, preceded by a Thumb2 mode switch if required (using explicit wide encodings where appropriate). The label itself can be moved to the start of code [where it belongs] due to the larger range of branch instructions as compared to adr instructions.
--- arch/arm/boot/compressed/efi-header.S | 4 +--- arch/arm/boot/compressed/head.S | 17 ++++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-)
arch/arm/boot/compressed/efi-header.S +1 -3
@@ -17,14 +17,12 @@ @ there. .inst 'M' | ('Z' << 8) | (0x1310 << 16) @ tstne r0, #0x4d000 #else - mov r0, r0 + W(mov) r0, r0 #endif .endm .macro __EFI_HEADER #ifdef CONFIG_EFI_STUB - b __efi_start - .set start_offset, __efi_start - start .org start + 0x3c @
arch/arm/boot/compressed/head.S +10 -7
@@ -130,19 +130,22 @@ start: .rept 7 __nop .endr - ARM( mov r0, r0 ) - ARM( b 1f ) - THUMB( badr r12, 1f ) - THUMB( bx r12 ) +#ifndef CONFIG_THUMB2_KERNEL + mov r0, r0 +#else + AR_CLASS( sub pc, pc, #3 ) @ A/R: switch to Thumb2 mode + M_CLASS( nop.w ) @ M: already in Thumb2 mode + .thumb +#endif + W(b) 1f .word _magic_sig @ Magic numbers to help the loader .word _magic_start @ absolute load/run zImage address .word _magic_end @ zImage end address .word 0x04030201 @ endianness flag - THUMB( .thumb ) -1: __EFI_HEADER - + __EFI_HEADER +1: ARM_BE8( setend be ) @ go BE8 if compiled for BE8 AR_CLASS( mrs r9, cpsr ) #ifdef CONFIG_ARM_VIRT_EXT
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 38/98 gpu: ipu-v3: Fix CSI selection for VDIC
In reply to Sasha LevinFrom: Marek Vasut <[email protected]>
[ Upstream commit b7dfee2433576f1f030cb84cdb04b70f36554992 ]
The description of the CSI_SEL bit in the i.MX6 reference manual is incorrect. It states "This bit defines which CSI is the input to the IC. This bit is effective only if IC_INPUT is bit cleared".
Quoted 1 line
From experiment it was found this is in fact not correct. The
CSI_SEL
bit selects which CSI is input to _both_ the VDIC _and_ the IC. If the IC_INPUT bit is set so that the IC is receiving from the VDIC, the IC ignores the CSI_SEL bit, but CSI_SEL still selects which CSI the VDIC receives from in that case.
--- drivers/gpu/ipu-v3/ipu-common.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/gpu/ipu-v3/ipu-common.c +8 -7
@@ -715,15 +715,16 @@ void ipu_set_ic_src_mux(struct ipu_soc *ipu, int csi_id, bool vdi)spin_lock_irqsave (&ipu->lock, flags); val =ipu_cm_read (ipu,IPU_CONF ); -if (vdi) { +if (vdi) val |=IPU_CONF_IC_INPUT ; - }else { +else val &= ~IPU_CONF_IC_INPUT ; -if (csi_id ==1 ) - val |=IPU_CONF_CSI_SEL ; -else - val &= ~IPU_CONF_CSI_SEL ; - } + +if (csi_id ==1 ) + val |=IPU_CONF_CSI_SEL ; +else + val &= ~IPU_CONF_CSI_SEL ; +ipu_cm_write (ipu, val,IPU_CONF );spin_unlock_irqrestore (&ipu->lock, flags);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 39/98 elevator: fix truncation of icq_cache_name
In reply to Sasha LevinFrom: Eric Biggers <[email protected]>
[ Upstream commit 9bd2bbc01d17ddd567cc0f81f77fe1163e497462 ]
gcc 7.1 reports the following warning:
block/elevator.c: In function ‘elv_register’:
block/elevator.c:898:5: warning: ‘snprintf’ output may be truncated before the last format character [-Wformat-truncation=]
"%s_io_cq", e->elevator_name);
^~~~~~~~~~
block/elevator.c:897:3: note: ‘snprintf’ output between 7 and 22 bytes into a destination of size 21
snprintf(e->icq_cache_name, sizeof(e->icq_cache_name),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"%s_io_cq", e->elevator_name);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~The bug is that the name of the icq_cache is 6 characters longer than the elevator name, but only ELV_NAME_MAX + 5 characters were reserved for it --- so in the case of a maximum-length elevator name, the 'q' character in "_io_cq" would be truncated by snprintf(). Fix it by reserving ELV_NAME_MAX + 6 characters instead.
--- include/linux/elevator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/elevator.h +1 -1
@@ -102,7 +102,7 @@ struct elevator_typestruct module *elevator_owner;/* managed by elevator core */ -char icq_cache_name[ELV_NAME_MAX +5 ];/* elvname + "_io_cq" */ +char icq_cache_name[ELV_NAME_MAX +6 ];/* elvname + "_io_cq" */ struct list_head list; };
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 40/98 net: stmmac: ensure jumbo_frm error return is correctly checked for -ve value
In reply to Sasha LevinFrom: Colin Ian King <[email protected]>
[ Upstream commit 594238158bf748c285f0a73222cd9b7ccf3c525d ]
The current comparison of entry < 0 will never be true since entry is an unsigned integer. Make entry an int to ensure -ve error return values from the call to jumbo_frm are correctly being caught.
Detected by CoverityScan, CID#1238760 ("Macro compares unsigned to 0")
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +2 -1
@@ -2199,7 +2199,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)unsigned int nopaged_len =skb_headlen (skb);int i, csum_insertion =0 , is_jumbo =0 ;int nfrags =skb_shinfo (skb)->nr_frags; -unsigned int entry, first_entry; +int entry; +unsigned int first_entry;struct dma_desc *desc, *first;unsigned int enh_desc;unsigned int des;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 41/98 Btrfs: clear EXTENT_DEFRAG bits in finish_ordered_io
In reply to Sasha LevinFrom: Liu Bo <[email protected]>
[ Upstream commit 452e62b71fbbefe2646fad3a968371a026936c6d ]
Before this, we use 'filled' mode here, ie. if all range has been filled with EXTENT_DEFRAG bits, get to clear it, but if the defrag range joins the adjacent delalloc range, then we'll have EXTENT_DEFRAG bits in extent_state until releasing this inode's pages, and that prevents extent_data from being freed.
This clears the bit if any was found within the ordered extent.
--- fs/btrfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/inode.c +1 -1
@@ -2966,7 +2966,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) ret =test_range_bit (io_tree, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len -1 , -EXTENT_DEFRAG ,1 , cached_state); +EXTENT_DEFRAG ,0 , cached_state);if (ret) {u64 last_snapshot =btrfs_root_last_snapshot (&root->root_item);if (0 && last_snapshot >=BTRFS_I (inode)->generation)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 42/98 ufs: we need to sync inode before freeing it
In reply to Sasha LevinFrom: Al Viro <[email protected]>
[ Upstream commit 67a70017fa0a152657bc7e337e69bb9c9f5549bf ]
--- fs/ufs/inode.c | 1 + 1 file changed, 1 insertion(+)
fs/ufs/inode.c +1 -0
@@ -846,6 +846,7 @@ void ufs_evict_inode(struct inode * inode) inode->i_size =0 ;if (inode->i_blocks)ufs_truncate_blocks (inode); +ufs_update_inode (inode,inode_needs_sync (inode)); }invalidate_inode_buffers (inode);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 43/98 net/mlx5e: Fix fixpoint divide exception in mlx5e_am_stats_compare
In reply to Sasha LevinFrom: Talat Batheesh <[email protected]>
[ Upstream commit e58edaa4863583b54409444f11b4f80dff0af1cd ]
Helmut reported a bug about division by zero while running traffic and doing physical cable pull test.
When the cable unplugged the ppms become zero, so when dividing the current ppms by the previous ppms in the next dim iteration there is division by zero.
This patch prevent this division for both ppms and epms.
--- drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c +6 -0
@@ -197,9 +197,15 @@ static int mlx5e_am_stats_compare(struct mlx5e_rx_am_stats *curr,return (curr->bpms > prev->bpms) ?MLX5E_AM_STATS_BETTER :MLX5E_AM_STATS_WORSE ; +if (!prev->ppms) +return curr->ppms ?MLX5E_AM_STATS_BETTER : +MLX5E_AM_STATS_SAME ; +if (IS_SIGNIFICANT_DIFF (curr->ppms, prev->ppms))return (curr->ppms > prev->ppms) ?MLX5E_AM_STATS_BETTER :MLX5E_AM_STATS_WORSE ; +if (!prev->epms) +return MLX5E_AM_STATS_SAME ;if (IS_SIGNIFICANT_DIFF (curr->epms, prev->epms)) return (curr->epms < prev->epms) ? MLX5E_AM_STATS_BETTER :
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 44/98 ip6_tunnel: Correct tos value in collect_md mode
In reply to Sasha LevinFrom: Haishuang Yan <[email protected]>
[ Upstream commit 46f8cd9d2fc1e4e8b82b53a0007f6c92e80c930b ]
Same as ip_gre, geneve and vxlan, use key->tos as traffic class value.
encapsulated packets”)
--- net/ipv6/ip6_tunnel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/ipv6/ip6_tunnel.c +2 -2
@@ -1258,7 +1258,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto =IPPROTO_IPIP ; fl6.daddr = key->u.ipv6.dst; fl6.flowlabel = key->label; - dsfield =ip6_tclass (key->label); + dsfield = key->tos; }else {if (!(t->parms.flags &IP6_TNL_F_IGN_ENCAP_LIMIT )) encap_limit = t->parms.encap_limit;
@@ -1329,7 +1329,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowi6_proto =IPPROTO_IPV6 ; fl6.daddr = key->u.ipv6.dst; fl6.flowlabel = key->label; - dsfield =ip6_tclass (key->label); + dsfield = key->tos; }else { offset =ip6_tnl_parse_tlv_enc_lim (skb,skb_network_header (skb));/* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 45/98 net/mlx5: Fix driver load error flow when firmware is stuck
In reply to Sasha LevinFrom: Gal Pressman <[email protected]>
[ Upstream commit 8ce59b16b4b6eacedaec1f7b652b4781cdbfe15f ]
When wait for firmware init fails, previous code would mistakenly return success and cause inconsistency in the driver state.
--- drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/main.c +1 -1
@@ -957,7 +957,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,if (err) {dev_err (&dev->pdev->dev,"Firmware over %d MS in pre-initializing state, aborting\n" ,FW_PRE_INIT_TIMEOUT_MILI ); - goto out; + goto out_err; } err =mlx5_cmd_init (dev);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 46/98 perf evsel: Fix probing of precise_ip level for default cycles event
In reply to Sasha LevinFrom: Arnaldo Carvalho de Melo <[email protected]>
[ Upstream commit 7a1ac110c22eb726684c837544a2d42c33e07be7 ]
Since commit 18e7a45af91a ("perf/x86: Reject non sampling events with precise_ip") returns -EINVAL for sys_perf_event_open() with an attribute with (attr.precise_ip > 0 && attr.sample_period == 0), just like is done in the routine used to probe the max precise level when no events were passed to 'perf record' or 'perf top', i.e.:
perf_evsel__new_cycles()
perf_event_attr__set_max_precise_ip()
The x86 code, in x86_pmu_hw_config(), which is called all the way from sys_perf_event_open() did, starting with the aforementioned commit:
/* There's no sense in having PEBS for non sampling events: */
if (!is_sampling_event(event))
return -EINVAL;Which makes it fail for cycles:ppp, cycles:pp and cycles:p, always using just the non precise cycles variant.
To make sure that this is the case, I tested it, before this patch, with:
# perf probe -L x86_pmu_hw_config
<x86_pmu_hw_config@/home/acme/git/linux/arch/x86/events/core.c:0>
0 int x86_pmu_hw_config(struct perf_event *event)
1 {
2 if (event->attr.precise_ip) {
<SNIP>
17 if (event->attr.precise_ip > precise)
18 return -EOPNOTSUPP; /* There's no sense in having PEBS for non sampling events: */
21 if (!is_sampling_event(event))
22 return -EINVAL;
}
<SNIP>
# perf probe x86_pmu_hw_config:22
Added new events:
probe:x86_pmu_hw_config (on x86_pmu_hw_config:22)
probe:x86_pmu_hw_config_1 (on x86_pmu_hw_config:22)You can now use it in all perf tools, such as:
perf record -e probe:x86_pmu_hw_config_1 -aR sleep 1
# perf trace -e perf_event_open,probe:x86_pmu_hwconfig*/max-stack=16/ perf record usleep 1
0.000 ( 0.015 ms): perf/4150 perf_event_open(attr_uptr: 0x7ffebc8ba110, cpu: -1, group_fd: -1 ) ...
0.015 ( ): probe:x86_pmu_hw_config:(ffffffff9c0065e1))
x86_pmu_hw_config ([kernel.kallsyms])
hsw_hw_config ([kernel.kallsyms])
x86_pmu_event_init ([kernel.kallsyms])
perf_try_init_event ([kernel.kallsyms])
perf_event_alloc ([kernel.kallsyms])
SYSC_perf_event_open ([kernel.kallsyms])
sys_perf_event_open ([kernel.kallsyms])
do_syscall_64 ([kernel.kallsyms])
return_from_SYSCALL_64 ([kernel.kallsyms])
syscall (/usr/lib64/libc-2.24.so)
perf_event_attr__set_max_precise_ip (/home/acme/bin/perf)
perf_evsel__new_cycles (/home/acme/bin/perf)
perf_evlist__add_default (/home/acme/bin/perf)
cmd_record (/home/acme/bin/perf)
run_builtin (/home/acme/bin/perf)
handle_internal_command (/home/acme/bin/perf)
0.000 ( 0.021 ms): perf/4150 ... [continued]: perf_event_open()) = -1 EINVAL Invalid argument
0.023 ( 0.002 ms): perf/4150 perf_event_open(attr_uptr: 0x7ffebc8ba110, cpu: -1, group_fd: -1 ) ...
0.025 ( ): probe:x86_pmu_hw_config:(ffffffff9c0065e1))
x86_pmu_hw_config ([kernel.kallsyms])
hsw_hw_config ([kernel.kallsyms])
x86_pmu_event_init ([kernel.kallsyms])
perf_try_init_event ([kernel.kallsyms])
perf_event_alloc ([kernel.kallsyms])
SYSC_perf_event_open ([kernel.kallsyms])
sys_perf_event_open ([kernel.kallsyms])
do_syscall_64 ([kernel.kallsyms])
return_from_SYSCALL_64 ([kernel.kallsyms])
syscall (/usr/lib64/libc-2.24.so)
perf_event_attr__set_max_precise_ip (/home/acme/bin/perf)
perf_evsel__new_cycles (/home/acme/bin/perf)
perf_evlist__add_default (/home/acme/bin/perf)
cmd_record (/home/acme/bin/perf)
run_builtin (/home/acme/bin/perf)
handle_internal_command (/home/acme/bin/perf)
0.023 ( 0.004 ms): perf/4150 ... [continued]: perf_event_open()) = -1 EINVAL Invalid argument
0.028 ( 0.002 ms): perf/4150 perf_event_open(attr_uptr: 0x7ffebc8ba110, cpu: -1, group_fd: -1 ) ...
0.030 ( ): probe:x86_pmu_hw_config:(ffffffff9c0065e1))
x86_pmu_hw_config ([kernel.kallsyms])
hsw_hw_config ([kernel.kallsyms])
x86_pmu_event_init ([kernel.kallsyms])
perf_try_init_event ([kernel.kallsyms])
perf_event_alloc ([kernel.kallsyms])
SYSC_perf_event_open ([kernel.kallsyms])
sys_perf_event_open ([kernel.kallsyms])
do_syscall_64 ([kernel.kallsyms])
return_from_SYSCALL_64 ([kernel.kallsyms])
syscall (/usr/lib64/libc-2.24.so)
perf_event_attr__set_max_precise_ip (/home/acme/bin/perf)
perf_evsel__new_cycles (/home/acme/bin/perf)
perf_evlist__add_default (/home/acme/bin/perf)
cmd_record (/home/acme/bin/perf)
run_builtin (/home/acme/bin/perf)
handle_internal_command (/home/acme/bin/perf)
0.028 ( 0.004 ms): perf/4150 ... [continued]: perf_event_open()) = -1 EINVAL Invalid argument
41.018 ( 0.012 ms): perf/4150 perf_event_open(attr_uptr: 0x7ffebc8b5dd0, pid: -1, group_fd: -1, flags: FD_CLOEXEC) = 4
41.065 ( 0.011 ms): perf/4150 perf_event_open(attr_uptr: 0x3c7db78, pid: -1, group_fd: -1, flags: FD_CLOEXEC) = 4
41.080 ( 0.006 ms): perf/4150 perf_event_open(attr_uptr: 0x3c7db78, pid: -1, group_fd: -1, flags: FD_CLOEXEC) = 4
41.103 ( 0.010 ms): perf/4150 perf_event_open(attr_uptr: 0x3c4e748, pid: 4151 (perf), group_fd: -1, flags: FD_CLOEXEC) = 4
41.115 ( 0.006 ms): perf/4150 perf_event_open(attr_uptr: 0x3c4e748, pid: 4151 (perf), cpu: 1, group_fd: -1, flags: FD_CLOEXEC) = 5
41.122 ( 0.004 ms): perf/4150 perf_event_open(attr_uptr: 0x3c4e748, pid: 4151 (perf), cpu: 2, group_fd: -1, flags: FD_CLOEXEC) = 6
41.128 ( 0.008 ms): perf/4150 perf_event_open(attr_uptr: 0x3c4e748, pid: 4151 (perf), cpu: 3, group_fd: -1, flags: FD_CLOEXEC) = 8
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.017 MB perf.data (2 samples) ]
#I.e. that return -EINVAL in x86_pmu_hw_config() is hit three times.
So fix it by just setting attr.sample_period
Now, after this patch:
# perf trace --max-stack=2 -e perf_event_open,probe:x86_pmu_hw_config* perf record usleep 1
[ perf record: Woken up 1 times to write data ]
0.000 ( 0.017 ms): perf/8469 perf_event_open(attr_uptr: 0x7ffe36c27d10, pid: -1, cpu: 3, group_fd: -1, flags: FD_CLOEXEC) = 4
syscall (/usr/lib64/libc-2.24.so)
perf_event_open_cloexec_flag (/home/acme/bin/perf)
0.050 ( 0.031 ms): perf/8469 perf_event_open(attr_uptr: 0x24ebb78, pid: -1, group_fd: -1, flags: FD_CLOEXEC) = 4
syscall (/usr/lib64/libc-2.24.so)
perf_evlist__config (/home/acme/bin/perf)
0.092 ( 0.040 ms): perf/8469 perf_event_open(attr_uptr: 0x24ebb78, pid: -1, group_fd: -1, flags: FD_CLOEXEC) = 4
syscall (/usr/lib64/libc-2.24.so)
perf_evlist__config (/home/acme/bin/perf)
0.143 ( 0.007 ms): perf/8469 perf_event_open(attr_uptr: 0x24bc748, cpu: -1, group_fd: -1 ) = 4
syscall (/usr/lib64/libc-2.24.so)
perf_event_attr__set_max_precise_ip (/home/acme/bin/perf)
0.161 ( 0.007 ms): perf/8469 perf_event_open(attr_uptr: 0x24bc748, pid: 8470 (perf), group_fd: -1, flags: FD_CLOEXEC) = 4
syscall (/usr/lib64/libc-2.24.so)
perf_evsel__open (/home/acme/bin/perf)
0.171 ( 0.005 ms): perf/8469 perf_event_open(attr_uptr: 0x24bc748, pid: 8470 (perf), cpu: 1, group_fd: -1, flags: FD_CLOEXEC) = 5
syscall (/usr/lib64/libc-2.24.so)
perf_evsel__open (/home/acme/bin/perf)
0.180 ( 0.007 ms): perf/8469 perf_event_open(attr_uptr: 0x24bc748, pid: 8470 (perf), cpu: 2, group_fd: -1, flags: FD_CLOEXEC) = 6
syscall (/usr/lib64/libc-2.24.so)
perf_evsel__open (/home/acme/bin/perf)
0.190 ( 0.005 ms): perf/8469 perf_event_open(attr_uptr: 0x24bc748, pid: 8470 (perf), cpu: 3, group_fd: -1, flags: FD_CLOEXEC) = 8
syscall (/usr/lib64/libc-2.24.so)
perf_evsel__open (/home/acme/bin/perf)
[ perf record: Captured and wrote 0.017 MB perf.data (7 samples) ]
#The probe one called from perf_event_attr__set_max_precise_ip() works the first time, with attr.precise_ip = 3, wit hthe next ones being the per cpu ones for the cycles:ppp event.
And here is the text from a report and alternative proposed patch by Thomas-Mich Richter:
---
On s390 the counter and sampling facility do not support a precise IP skid level and sometimes returns EOPNOTSUPP when structure member precise_ip in struct perf_event_attr is not set to zero.
On s390 commnd 'perf record -- true' fails with error EOPNOTSUPP. This happens only when no events are specified on command line.
The functions called are
...
--> perf_evlist__add_default
--> perf_evsel__new_cycles
--> perf_event_attr__set_max_precise_ipThe last function determines the value of structure member precise_ip by invoking the perf_event_open() system call and checking the return code. The first successful open is the value for precise_ip.
However the value is determined without setting member sample_period and indicates no sampling.
On s390 the counter facility and sampling facility are different. The above procedure determines a precise_ip value of 3 using the counter facility. Later it uses the sampling facility with a value of 3 and fails with EOPNOTSUPP.
---
v2: Older compilers (e.g. gcc 4.4.7) don't support referencing members
of unnamed union members in the container struct initialization, so
move from:
struct perf_event_attr attr = {
...
.sample_period = 1,
};to right after it as:
struct perf_event_attr attr = {
...
};
attr.sample_period = 1;v3: We need to reset .sample_period to 0 to let the users of perf_evsel__new_cycles() to properly setup attr.sample_period or attr.sample_freq. Reported by Ingo Molnar.
--- tools/perf/tests/task-exit.c | 2 +- tools/perf/util/evsel.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-)
tools/perf/tests/task-exit.c +1 -1
@@ -82,7 +82,7 @@ int test__task_exit(int subtest __maybe_unused) evsel =perf_evlist__first (evlist); evsel->attr.task =1 ; - evsel->attr.sample_freq =0 ; + evsel->attr.sample_freq =1 ; evsel->attr.inherit =0 ; evsel->attr.watermark =0 ; evsel->attr.wakeup_events =1 ;
tools/perf/util/evsel.c +12 -0
@@ -263,8 +263,20 @@ struct perf_evsel *perf_evsel__new_cycles(void)struct perf_evsel *evsel;event_attr_init (&attr); +/* +* Unnamed union member, not supported as struct member named +* initializer in older compilers such as gcc 4.4.7 +* +* Just for probing the precise_ip: +*/ + attr.sample_period =1 ;perf_event_attr__set_max_precise_ip (&attr); +/* +* Now let the usual logic to set up the perf_event_attr defaults +* to kick in when we return and before perf_evsel__open() is called. +*/ + attr.sample_period =0 ; evsel =perf_evsel__new (&attr);if (evsel ==NULL )
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 47/98 perf probe: Fix probe definition for inlined functions
In reply to Sasha LevinFrom: Björn Töpel <[email protected]>
[ Upstream commit 7598f8bc1383ffd77686cb4e92e749bef3c75937 ]
In commit 613f050d68a8 ("perf probe: Fix to probe on gcc generated functions in modules"), the offset from symbol is, incorrectly, added to the trace point address. This leads to incorrect probe trace points for inlined functions and when using relative line number on symbols.
Prior this patch:
$ perf probe -m nf_nat -D in_range p:probe/in_range nf_nat:in_range.isra.9+0 $ perf probe -m i40e -D i40e_clean_rx_irq p:probe/i40e_clean_rx_irq i40e:i40e_napi_poll+2212 $ perf probe -m i40e -D i40e_clean_rx_irq:16 p:probe/i40e_clean_rx_irq i40e:i40e_lan_xmit_frame+626
After:
$ perf probe -m nf_nat -D in_range p:probe/in_range nf_nat:in_range.isra.9+0 $ perf probe -m i40e -D i40e_clean_rx_irq p:probe/i40e_clean_rx_irq i40e:i40e_napi_poll+1106 $ perf probe -m i40e -D i40e_clean_rx_irq:16 p:probe/i40e_clean_rx_irq i40e:i40e_napi_poll+2665
Committer testing:
Using 'pfunct', a tool found in the 'dwarves' package [1], one can ask what are the functions that while not being explicitely marked as inline, were inlined by the compiler:
# pfunct --cc_inlined /lib/modules/4.12.0-rc4+/kernel/drivers/net/ethernet/intel/e1000e/e1000e.ko | head __ew32 e1000_regdump e1000e_dump_ps_pages e1000_desc_unused e1000e_systim_to_hwtstamp e1000e_rx_hwtstamp e1000e_update_rdt_wa e1000e_update_tdt_wa e1000_put_txbuf e1000_consume_page
Then ask 'perf probe' to produce the kprobe_tracer probe definitions for two of them:
# perf probe -m e1000e -D e1000e_rx_hwtstamp p:probe/e1000e_rx_hwtstamp e1000e:e1000_receive_skb+74
# perf probe -m e1000e -D e1000_consume_page p:probe/e1000_consume_page e1000e:e1000_clean_jumbo_rx_irq+876 p:probe/e1000_consume_page_1 e1000e:e1000_clean_jumbo_rx_irq+1506 p:probe/e1000_consume_page_2 e1000e:e1000_clean_rx_irq_ps+1074
Now lets concentrate on the 'e1000_consume_page' one, that was inlined twice in e1000_clean_jumbo_rx_irq(), lets see what readelf says about the DWARF tags for that function:
$ readelf -wi /lib/modules/4.12.0-rc4+/kernel/drivers/net/ethernet/intel/e1000e/e1000e.ko
<SNIP>
<1><13e27b>: Abbrev Number: 121 (DW_TAG_subprogram)
<13e27c> DW_AT_name : (indirect string, offset: 0xa8945): e1000_clean_jumbo_rx_irq
<13e287> DW_AT_low_pc : 0x17a30
<3><13e6ef>: Abbrev Number: 119 (DW_TAG_inlined_subroutine)
<13e6f0> DW_AT_abstract_origin: <0x13ed2c>
<13e6f4> DW_AT_low_pc : 0x17be6
<SNIP>
<1><13ed2c>: Abbrev Number: 142 (DW_TAG_subprogram)
<13ed2e> DW_AT_name : (indirect string, offset: 0xa54c3): e1000_consume_pageSo, the first time in e1000_clean_jumbo_rx_irq() where e1000_consume_page() is inlined is at PC 0x17be6, which subtracted from e1000_clean_jumbo_rx_irq()'s address, gives us the offset we should use in the probe definition:
0x17be6 - 0x17a30 = 438
but above we have 876, which is twice as much.
Lets see the second inline expansion of e1000_consume_page() in e1000_clean_jumbo_rx_irq():
<3><13e86e>: Abbrev Number: 119 (DW_TAG_inlined_subroutine)
<13e86f> DW_AT_abstract_origin: <0x13ed2c>
<13e873> DW_AT_low_pc : 0x17d21 0x17d21 - 0x17a30 = 753
So we where adding it at twice the offset from the containing function as we should.
And then after this patch:
# perf probe -m e1000e -D e1000e_rx_hwtstamp p:probe/e1000e_rx_hwtstamp e1000e:e1000_receive_skb+37
# perf probe -m e1000e -D e1000_consume_page p:probe/e1000_consume_page e1000e:e1000_clean_jumbo_rx_irq+438 p:probe/e1000_consume_page_1 e1000e:e1000_clean_jumbo_rx_irq+753 p:probe/e1000_consume_page_2 e1000e:e1000_clean_jumbo_rx_irq+1353 #
Which matches the two first expansions and shows that because we were doubling the offset it would spill over the next function:
readelf -sw /lib/modules/4.12.0-rc4+/kernel/drivers/net/ethernet/intel/e1000e/e1000e.ko
673: 0000000000017a30 1626 FUNC LOCAL DEFAULT 2 e1000_clean_jumbo_rx_irq 674: 0000000000018090 2013 FUNC LOCAL DEFAULT 2 e1000_clean_rx_irq_ps
This is the 3rd inline expansion of e1000_consume_page() in e1000_clean_jumbo_rx_irq():
<3><13ec77>: Abbrev Number: 119 (DW_TAG_inlined_subroutine)
<13ec78> DW_AT_abstract_origin: <0x13ed2c>
<13ec7c> DW_AT_low_pc : 0x17f79 0x17f79 - 0x17a30 = 1353
So:
0x17a30 + 2 * 1353 = 0x184c2
And:
0x184c2 - 0x18090 = 1074
Which explains the bogus third expansion for e1000_consume_page() to end up at:
p:probe/e1000_consume_page_2 e1000e:e1000_clean_rx_irq_ps+1074
All fixed now :-)
[1] https://git.kernel.org/pub/scm/devel/pahole/pahole.git/
--- tools/perf/util/probe-event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/probe-event.c +1 -1
@@ -615,7 +615,7 @@ static int post_process_probe_trace_point(struct probe_trace_point *tp, struct map *map, unsigned long offs) {struct symbol *sym; -u64 addr = tp->address + tp->offset - offs; +u64 addr = tp->address - offs; sym =map__find_symbol (map, addr);if (!sym)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 48/98 net/mlx5: Fix health work queue spin lock to IRQ safe
In reply to Sasha LevinFrom: Moshe Shemesh <[email protected]>
[ Upstream commit 6377ed0bbae6fa28853e1679d068a9106c8a8908 ]
spin_lock/unlock of health->wq_lock should be IRQ safe. It was changed to spin_lock_irqsave since adding commit 0179720d6be2 ("net/mlx5: Introduce trigger_health_work function") which uses spin_lock from asynchronous event (IRQ) context.
Thus, all spin_lock/unlock of health->wq_lock should have been moved to IRQ safe mode.
However, one occurrence on new code using this lock missed that change, resulting in possible deadlock:
kernel: Possible unsafe locking scenario:
kernel: CPU0
kernel: ----
kernel: lock(&(&health->wq_lock)->rlock);
kernel: <Interrupt>
kernel: lock(&(&health->wq_lock)->rlock);
kernel: #012 *** DEADLOCK ***
--- drivers/net/ethernet/mellanox/mlx5/core/health.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/health.c +3 -2
@@ -369,10 +369,11 @@ void mlx5_drain_health_wq(struct mlx5_core_dev *dev)void mlx5_drain_health_recovery (struct mlx5_core_dev *dev) {struct mlx5_core_health *health = &dev->priv.health; +unsigned long flags; -spin_lock (&health->wq_lock); +spin_lock_irqsave (&health->wq_lock, flags);set_bit (MLX5_DROP_NEW_RECOVERY_WORK , &health->flags); -spin_unlock (&health->wq_lock); +spin_unlock_irqrestore (&health->wq_lock, flags);cancel_delayed_work_sync (&dev->priv.health.recover_work); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 49/98 usb: renesas_usbhs: gadget: fix spin_lock_init() for &uep->lock
In reply to Sasha LevinFrom: Yoshihiro Shimoda <[email protected]>
[ Upstream commit 14a8d4bfc2102f85ce097563d151370c91c1898a ]
This patch fixes an issue that the spin_lock_init() is not called for almost all pipes. Otherwise, the lockdep output the following message when we connect a usb cable using g_ncm:
INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.
--- drivers/usb/renesas_usbhs/mod_gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/renesas_usbhs/mod_gadget.c +1 -1
@@ -1085,7 +1085,6 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) ret = -ENOMEM ; goto usbhs_mod_gadget_probe_err_gpriv; } -spin_lock_init (&uep->lock); gpriv->transceiver =usb_get_phy (USB_PHY_TYPE_UNDEFINED ); dev_info(dev, "%stransceiver found\n",
@@ -1135,6 +1134,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) uep->ep.name = uep->ep_name; uep->ep.ops = &usbhsg_ep_ops;INIT_LIST_HEAD (&uep->ep.ep_list); +spin_lock_init (&uep->lock);/* init DCP */ if (usbhsg_is_dcp (uep)) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 50/98 usb: renesas_usbhs: gadget: fix unused-but-set-variable warning
In reply to Sasha LevinFrom: Yoshihiro Shimoda <[email protected]>
[ Upstream commit b7d44c36a6f6d956e1539e0dd42f98b26e5a4684 ]
The commit b8b9c974afee ("usb: renesas_usbhs: gadget: disable all eps when the driver stops") causes the unused-but-set-variable warning. But, if the usbhsg_ep_disable() will return non-zero value, udc/core.c doesn't clear the ep->enabled flag. So, this driver should not return non-zero value, if the pipe is zero because this means the pipe is already disabled. Otherwise, the ep->enabled flag is never cleared when the usbhsg_ep_disable() is called by the renesas_usbhs driver first.
--- drivers/usb/renesas_usbhs/mod_gadget.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/usb/renesas_usbhs/mod_gadget.c +1 -4
@@ -639,14 +639,11 @@ static int usbhsg_ep_disable(struct usb_ep *ep)struct usbhsg_uep *uep =usbhsg_ep_to_uep (ep);struct usbhs_pipe *pipe;unsigned long flags; -int ret =0 ;spin_lock_irqsave (&uep->lock, flags); pipe =usbhsg_uep_to_pipe (uep); -if (!pipe) { - ret = -EINVAL ; +if (!pipe) goto out; - }usbhsg_pipe_disable (uep);usbhs_pipe_free (pipe);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 51/98 usb: dwc3: omap: remove IRQ_NOAUTOEN used with shared irq
In reply to Sasha LevinFrom: Vignesh R <[email protected]>
[ Upstream commit ee249b4554947de3be77be4e9e6077b20c0fe055 ]
IRQ_NOAUTOEN cannot be used with shared IRQs, since commit 04c848d39879 ("genirq: Warn when IRQ_NOAUTOEN is used with shared interrupts") and kernel now throws a warn dump. But OMAP DWC3 driver uses this flag. As per commit 12a7f17fac5b ("usb: dwc3: omap: fix race of pm runtime with irq handler in probe") that introduced this flag, PM runtime can race with IRQ handler when deferred probing happens due to extcon, therefore IRQ_NOAUTOEN needs to be set so that irq is not enabled until extcon is registered.
Remove setting of IRQ_NOAUTOEN and move the registration of shared irq to a point after dwc3_omap_extcon_register() and of_platform_populate(). This avoids possibility of probe deferring and above said race condition.
--- drivers/usb/dwc3/dwc3-omap.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
drivers/usb/dwc3/dwc3-omap.c +8 -10
@@ -512,15 +512,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)/* check the DMA Status */ reg =dwc3_omap_readl (omap->base,USBOTGSS_SYSCONFIG ); -irq_set_status_flags (omap->irq,IRQ_NOAUTOEN ); - ret =devm_request_threaded_irq (dev, omap->irq, dwc3_omap_interrupt, - dwc3_omap_interrupt_thread,IRQF_SHARED , -"dwc3-omap" , omap); -if (ret) { -dev_err (dev,"failed to request IRQ #%d --> %d\n" , - omap->irq, ret); - goto err1; - } ret =dwc3_omap_extcon_register (omap);if (ret <0 )
@@ -532,8 +523,15 @@ static int dwc3_omap_probe(struct platform_device *pdev) goto err2; } + ret =devm_request_threaded_irq (dev, omap->irq, dwc3_omap_interrupt, + dwc3_omap_interrupt_thread,IRQF_SHARED , +"dwc3-omap" , omap); +if (ret) { +dev_err (dev,"failed to request IRQ #%d --> %d\n" , + omap->irq, ret); + goto err1; + }dwc3_omap_enable_irqs (omap); -enable_irq (omap->irq);return 0 ; err2:
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 52/98 clk: samsung: Fix m2m scaler clock on Exynos542x
In reply to Sasha LevinFrom: Andrzej Pietrasiewicz <[email protected]>
[ Upstream commit c07c1a0f68d0f2f7ca9aff924e2772526027b019 ]
The TOP "aclk400_mscl" clock should be kept enabled all the time to allow proper access to power management control for MSC power domain and devices that are a part of it. This change is required for the scaler to work properly after domain power on/off sequence.
--- drivers/clk/samsung/clk-exynos5420.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/samsung/clk-exynos5420.c +1 -1
@@ -987,7 +987,7 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {GATE (0 ,"aclk400_isp" ,"mout_user_aclk400_isp" ,GATE_BUS_TOP ,16 ,0 ,0 ),GATE (0 ,"aclk400_mscl" ,"mout_user_aclk400_mscl" , -GATE_BUS_TOP ,17 ,0 ,0 ), +GATE_BUS_TOP ,17 ,CLK_IS_CRITICAL ,0 ),GATE (0 ,"aclk200_disp1" ,"mout_user_aclk200_disp1" ,GATE_BUS_TOP ,18 ,CLK_IS_CRITICAL ,0 ), GATE(CLK_SCLK_MPHY_IXTAL24, "sclk_mphy_ixtal24", "mphy_refclk_ixtal24",
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 53/98 ptr_ring: fix up after recent ptr_ring changes
In reply to Sasha LevinFrom: "Michael S. Tsirkin" <[email protected]>
[ Upstream commit 5790eabc6e7c3ce2d6ca2e3bbf4de467ce2b64b3 ]
Add more stubs to make it build.
--- tools/virtio/ringtest/ptr_ring.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-)
tools/virtio/ringtest/ptr_ring.c +23 -6
@@ -15,24 +15,41 @@#define unlikely (x) (__builtin_expect(!!(x), 0))#define likely (x) (__builtin_expect(!!(x), 1))#define ALIGN (x, a) (((x) + (a) - 1) / (a) * (a)) +#define SIZE_MAX (~(size_t)0) +typedef pthread_spinlock_t spinlock_t ;typedef int gfp_t ; -static void *kmalloc (unsigned size,gfp_t gfp) -{ -return memalign (64 , size); -} +#define __GFP_ZERO 0x1 -static void *kzalloc (unsigned size,gfp_t gfp) +static void *kmalloc (unsigned size,gfp_t gfp) {void *p =memalign (64 , size);if (!p)return p; -memset (p,0 , size); +if (gfp & __GFP_ZERO) +memset (p,0 , size);return p; } +static inline void *kzalloc (unsigned size,gfp_t flags) +{ +return kmalloc (size, flags | __GFP_ZERO); +} + +static inline void *kmalloc_array (size_t n,size_t size,gfp_t flags) +{ +if (size !=0 && n >SIZE_MAX / size) +return NULL ; +return kmalloc (n * size, flags); +} + +static inline void *kcalloc (size_t n,size_t size,gfp_t flags) +{ +return kmalloc_array (n, size, flags | __GFP_ZERO); +} +static void kfree (void *p) {if (p)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 54/98 staging: wilc1000: Fix problem with wrong vif index
In reply to Sasha LevinFrom: Aditya Shankar <[email protected]>
[ Upstream commit 0e490657c7214cce33fbca3d88227298c5c968ae ]
The vif->idx value is always 0 for two interfaces.
wl->vif_num = 0;
loop {
...
vif->idx = wl->vif_num;
...
wl->vif_num = i;
....
i++;
...
}At present, vif->idx is assigned the value of wl->vif_num
at the beginning of this block and device is initialized
based on this index value.
In the next iteration, wl->vif_num is still 0 as it is only updated later but gets assigned to vif->idx in the beginning. This causes problems later when we try to reference a particular interface and also while configuring the firmware.
This patch moves the assignment to vif->idx from the beginning of the block to after wl->vif_num is updated with latest value of i.
--- drivers/staging/wilc1000/linux_wlan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/staging/wilc1000/linux_wlan.c +2 -1
@@ -1260,11 +1260,12 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,else strcpy (ndev->name,"p2p%d" ); - vif->idx = wl->vif_num; vif->wilc = *wilc; vif->ndev = ndev; wl->vif[i] = vif; wl->vif_num = i; + vif->idx = wl->vif_num; + ndev->netdev_ops = &wilc_netdev_ops; {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 55/98 rds: ib: Fix missing call to rds_ib_dev_put in rds_ib_setup_qp
In reply to Sasha LevinFrom: Dag Moxnes <[email protected]>
[ Upstream commit 91a825290ca4eae88603bc811bf74a45f94a3f46 ]
The function rds_ib_setup_qp is calling rds_ib_get_client_data and should correspondingly call rds_ib_dev_put. This call was lost in the non-error path with the introduction of error handling done in commit 3b12f73a5c29 ("rds: ib: add error handle")
--- net/rds/ib_cm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/rds/ib_cm.c +2 -1
@@ -505,7 +505,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)rdsdebug ("conn %p pd %p cq %p %p\n" , conn, ic->i_pd, ic->i_send_cq, ic->i_recv_cq); -return ret; + goto out; sends_out:vfree (ic->i_sends);
@@ -530,6 +530,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) ic->i_send_cq =NULL ; rds_ibdev_out:rds_ib_remove_conn (rds_ibdev, conn); +out:rds_ib_dev_put (rds_ibdev);return ret;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 56/98 iio: adc: Revert "axp288: Drop bogus AXP288_ADC_TS_PIN_CTRL register modifications"
In reply to Sasha LevinFrom: Hans de Goede <[email protected]>
[ Upstream commit 631b010abc5b57009c6a8328f51492665f6ef310 ]
Inheriting the ADC BIAS current settings from the BIOS instead of hardcoding then causes the AXP288 to disable charging (I think it mis-detects an overheated battery) on at least one model tablet.
So lets go back to hard coding the values, this reverts commit fa2849e9649b ("iio: adc: axp288: Drop bogus AXP288_ADC_TS_PIN_CTRL register modifications"), fixing charging not working on the model tablet in question.
The exact cause is not fully understood, hence the revert to a known working state.
--- drivers/iio/adc/axp288_adc.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
drivers/iio/adc/axp288_adc.c +31 -1
@@ -28,6 +28,8 @@#include <linux/iio/driver.h> #define AXP288_ADC_EN_MASK 0xF1 +#define AXP288_ADC_TS_PIN_GPADC 0xF2 +#define AXP288_ADC_TS_PIN_ON 0xF3enum axp288_adc_id {AXP288_ADC_TS ,
@@ -121,6 +123,16 @@ static int axp288_adc_read_channel(int *val, unsigned long address,return IIO_VAL_INT ; } +static int axp288_adc_set_ts (struct regmap *regmap,unsigned int mode, +unsigned long address) +{ +/* channels other than GPADC do not need to switch TS pin */ +if (address !=AXP288_GP_ADC_H ) +return 0 ; + +return regmap_write (regmap,AXP288_ADC_TS_PIN_CTRL , mode); +} +static int axp288_adc_read_raw (struct iio_dev *indio_dev,struct iio_chan_spec const *chan,int *val,int *val2,long mask)
@@ -131,7 +143,16 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,mutex_lock (&indio_dev->mlock);switch (mask) {case IIO_CHAN_INFO_RAW : +if (axp288_adc_set_ts (info->regmap,AXP288_ADC_TS_PIN_GPADC , + chan->address)) { +dev_err (&indio_dev->dev,"GPADC mode\n" ); + ret = -EINVAL ; +break ; + } ret =axp288_adc_read_channel (val, chan->address, info->regmap); +if (axp288_adc_set_ts (info->regmap,AXP288_ADC_TS_PIN_ON , + chan->address)) +dev_err (&indio_dev->dev,"TS pin restore\n" );break ;default : ret = -EINVAL ;
@@ -141,6 +162,15 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,return ret; } +static int axp288_adc_set_state (struct regmap *regmap) +{ +/* ADC should be always enabled for internal FG to function */ +if (regmap_write (regmap,AXP288_ADC_TS_PIN_CTRL ,AXP288_ADC_TS_PIN_ON )) +return -EIO ; + +return regmap_write (regmap,AXP20X_ADC_EN1 ,AXP288_ADC_EN_MASK ); +} +static const struct iio_info axp288_adc_iio_info = { .read_raw = &axp288_adc_read_raw, .driver_module =THIS_MODULE ,
@@ -169,7 +199,7 @@ static int axp288_adc_probe(struct platform_device *pdev)* Set ADC to enabled state at all time, including system suspend. * otherwise internal fuel gauge functionality may be affected. */ - ret =regmap_write (info->regmap,AXP20X_ADC_EN1 ,AXP288_ADC_EN_MASK ); + ret =axp288_adc_set_state (axp20x->regmap);if (ret) {dev_err (&pdev->dev,"unable to enable ADC device\n" );return ret;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 57/98 qed: Warn PTT usage by wrong hw-function
In reply to Sasha LevinFrom: "Mintz, Yuval" <[email protected]>
[ Upstream commit 3a50d3518dcba44f8a0f9356b7140fe1499984ea ]
PTT entries are per-hwfn; If some errneous flow is trying to use a PTT belonging to a differnet hwfn warn user, as this can break every register accessing flow later and is very hard to root-cause.
--- drivers/net/ethernet/qlogic/qed/qed_hw.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ethernet/qlogic/qed/qed_hw.c +7 -0
@@ -34,6 +34,7 @@ struct qed_ptt {struct list_head list_entry;unsigned int idx;struct pxp_ptt_entry pxp; +u8 hwfn_id; };struct qed_ptt_pool {
@@ -55,6 +56,7 @@ int qed_ptt_pool_alloc(struct qed_hwfn *p_hwfn) p_pool->ptts[i].idx = i; p_pool->ptts[i].pxp.offset =QED_BAR_INVALID_OFFSET ; p_pool->ptts[i].pxp.pretend.control =0 ; + p_pool->ptts[i].hwfn_id = p_hwfn->my_id;if (i >=RESERVED_PTT_MAX )list_add (&p_pool->ptts[i].list_entry, &p_pool->free_list);
@@ -169,6 +171,11 @@ static u32 qed_set_ptt(struct qed_hwfn *p_hwfn, offset = hw_addr - win_hw_addr; +if (p_ptt->hwfn_id != p_hwfn->my_id) +DP_NOTICE (p_hwfn, +"ptt[%d] of hwfn[%02x] is used by hwfn[%02x]!\n" , + p_ptt->idx, p_ptt->hwfn_id, p_hwfn->my_id); +/* Verify the address is within the window */ if (hw_addr < win_hw_addr || offset >=PXP_EXTERNAL_BAR_PF_WINDOW_SINGLE_SIZE ) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 58/98 ocfs2: fix deadlock caused by recursive locking in xattr
In reply to Sasha LevinFrom: Eric Ren <[email protected]>
[ Upstream commit 8818efaaacb78c60a9d90c5705b6c99b75d7d442 ]
Another deadlock path caused by recursive locking is reported. This kind of issue was introduced since commit 743b5f1434f5 ("ocfs2: take inode lock in ocfs2_iop_set/get_acl()"). Two deadlock paths have been fixed by commit b891fa5024a9 ("ocfs2: fix deadlock issue when taking inode lock at vfs entry points"). Yes, we intend to fix this kind of case in incremental way, because it's hard to find out all possible paths at once.
This one can be reproduced like this. On node1, cp a large file from home directory to ocfs2 mountpoint. While on node2, run setfacl/getfacl. Both nodes will hang up there. The backtraces:
On node1:
__ocfs2_cluster_lock.isra.39+0x357/0x740 [ocfs2] ocfs2_inode_lock_full_nested+0x17d/0x840 [ocfs2] ocfs2_write_begin+0x43/0x1a0 [ocfs2] generic_perform_write+0xa9/0x180 __generic_file_write_iter+0x1aa/0x1d0 ocfs2_file_write_iter+0x4f4/0xb40 [ocfs2] __vfs_write+0xc3/0x130 vfs_write+0xb1/0x1a0 SyS_write+0x46/0xa0
On node2:
__ocfs2_cluster_lock.isra.39+0x357/0x740 [ocfs2] ocfs2_inode_lock_full_nested+0x17d/0x840 [ocfs2] ocfs2_xattr_set+0x12e/0xe80 [ocfs2] ocfs2_set_acl+0x22d/0x260 [ocfs2] ocfs2_iop_set_acl+0x65/0xb0 [ocfs2] set_posix_acl+0x75/0xb0 posix_acl_xattr_set+0x49/0xa0 __vfs_setxattr+0x69/0x80 __vfs_setxattr_noperm+0x72/0x1a0 vfs_setxattr+0xa7/0xb0 setxattr+0x12d/0x190 path_setxattr+0x9f/0xb0 SyS_setxattr+0x14/0x20
Fix this one by using ocfs2_inode_{lock|unlock}_tracker, which is exported by commit 439a36b8ef38 ("ocfs2/dlmglue: prepare tracking logic to avoid recursive cluster lock").
--- fs/ocfs2/dlmglue.c | 4 ++++ fs/ocfs2/xattr.c | 23 +++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-)
fs/ocfs2/dlmglue.c +4 -0
@@ -2599,6 +2599,10 @@ void ocfs2_inode_unlock_tracker(struct inode *inode,struct ocfs2_lock_res *lockres; lockres = &OCFS2_I (inode)->ip_inode_lockres; +/* had_lock means that the currect process already takes the cluster +* lock previously. If had_lock is 1, we have nothing to do here, and +* it will get unlocked where we got the lock. +*/ if (!had_lock) {ocfs2_remove_holder (lockres, oh);ocfs2_inode_unlock (inode, ex);
fs/ocfs2/xattr.c +13 -10
@@ -1330,20 +1330,21 @@ static int ocfs2_xattr_get(struct inode *inode,void *buffer, size_t buffer_size) { - int ret; + int ret, had_lock;struct buffer_head *di_bh =NULL ; +struct ocfs2_lock_holder oh; - ret =ocfs2_inode_lock (inode, &di_bh,0 ); -if (ret <0 ) { -mlog_errno (ret); -return ret; + had_lock =ocfs2_inode_lock_tracker (inode, &di_bh,0 , &oh); +if (had_lock <0 ) { +mlog_errno (had_lock); +return had_lock; }down_read (&OCFS2_I (inode)->ip_xattr_sem); ret =ocfs2_xattr_get_nolock (inode, di_bh, name_index, name, buffer, buffer_size);up_read (&OCFS2_I (inode)->ip_xattr_sem); -ocfs2_inode_unlock (inode,0 ); +ocfs2_inode_unlock_tracker (inode,0 , &oh, had_lock);brelse (di_bh);
@@ -3539,11 +3540,12 @@ int ocfs2_xattr_set(struct inode *inode, {struct buffer_head *di_bh =NULL ;struct ocfs2_dinode *di; -int ret, credits, ref_meta =0 , ref_credits =0 ; +int ret, credits, had_lock, ref_meta =0 , ref_credits =0 ;struct ocfs2_super *osb =OCFS2_SB (inode->i_sb);struct inode *tl_inode = osb->osb_tl_inode;struct ocfs2_xattr_set_ctxt ctxt = {NULL ,NULL ,NULL , };struct ocfs2_refcount_tree *ref_tree =NULL ; +struct ocfs2_lock_holder oh;struct ocfs2_xattr_info xi = { .xi_name_index = name_index,
@@ -3574,8 +3576,9 @@ int ocfs2_xattr_set(struct inode *inode,return -ENOMEM ; } - ret =ocfs2_inode_lock (inode, &di_bh,1 ); -if (ret <0 ) { + had_lock =ocfs2_inode_lock_tracker (inode, &di_bh,1 , &oh); +if (had_lock <0 ) { + ret = had_lock;mlog_errno (ret); goto cleanup_nolock; }
@@ -3672,7 +3675,7 @@ int ocfs2_xattr_set(struct inode *inode,if (ret)mlog_errno (ret); } -ocfs2_inode_unlock (inode,1 ); +ocfs2_inode_unlock_tracker (inode,1 , &oh, had_lock); cleanup_nolock:brelse (di_bh);brelse (xbs.xattr_bh);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 59/98 net: cdc_ncm: GetNtbFormat endian fix
In reply to Sasha LevinFrom: Bjørn Mork <[email protected]>
[ Upstream commit 6314dab4b8fb8493d810e175cb340376052c69b6 ]
The GetNtbFormat and SetNtbFormat requests operate on 16 bit little endian values. We get away with ignoring this most of the time, because we only care about USB_CDC_NCM_NTB16_FORMAT which is 0x0000. This fails for USB_CDC_NCM_NTB32_FORMAT.
Fix comparison between LE value from device and constant by converting the constant to LE.
--- drivers/net/usb/cdc_ncm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/usb/cdc_ncm.c +2 -2
@@ -772,7 +772,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_int err;u8 iface_no;struct usb_cdc_parsed_header hdr; -u16 curr_ntb_format; +__le16 curr_ntb_format; ctx =kzalloc (sizeof (*ctx),GFP_KERNEL );if (!ctx)
@@ -890,7 +890,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ goto error2; } -if (curr_ntb_format ==USB_CDC_NCM_NTB32_FORMAT ) { +if (curr_ntb_format ==cpu_to_le16 (USB_CDC_NCM_NTB32_FORMAT )) {dev_info (&intf->dev,"resetting NTB format to 16-bit" ); err =usbnet_write_cmd (dev,USB_CDC_SET_NTB_FORMAT , USB_TYPE_CLASS | USB_DIR_OUT
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 60/98 sctp: use right member as the param of list_for_each_entry
In reply to Sasha LevinFrom: Xin Long <[email protected]>
[ Upstream commit a8dd397903a6e57157f6265911f7d35681364427 ]
Commit d04adf1b3551 ("sctp: reset owner sk for data chunks on out queues when migrating a sock") made a mistake that using 'list' as the param of list_for_each_entry to traverse the retransmit, sacked and abandoned queues, while chunks are using 'transmitted_list' to link into these queues.
It could cause NULL dereference panic if there are chunks in any of these queues when peeling off one asoc.
So use the chunk member 'transmitted_list' instead in this patch.
--- net/sctp/socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/sctp/socket.c +3 -3
@@ -185,13 +185,13 @@ static void sctp_for_each_tx_datachunk(struct sctp_association *asoc,list_for_each_entry (chunk, &t->transmitted, transmitted_list)cb (chunk); -list_for_each_entry (chunk, &q->retransmit, list) +list_for_each_entry (chunk, &q->retransmit, transmitted_list)cb (chunk); -list_for_each_entry (chunk, &q->sacked, list) +list_for_each_entry (chunk, &q->sacked, transmitted_list)cb (chunk); -list_for_each_entry (chunk, &q->abandoned, list) +list_for_each_entry (chunk, &q->abandoned, transmitted_list)cb (chunk);list_for_each_entry (chunk, &q->out_chunk_list, list)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 61/98 ALSA: hda - No loopback on ALC299 codec
In reply to Sasha LevinFrom: Takashi Iwai <[email protected]>
[ Upstream commit fa16b69f1299004b60b625f181143500a246e5cb ]
ALC299 has no loopback mixer, but the driver still tries to add a beep control over the mixer NID which leads to the error at accessing it. This patch fixes it by properly declaring mixer_nid=0 for this codec.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195775
--- sound/pci/hda/patch_realtek.c | 3 +++ 1 file changed, 3 insertions(+)
sound/pci/hda/patch_realtek.c +3 -0
@@ -6392,8 +6392,11 @@ static int patch_alc269(struct hda_codec *codec)break ;case 0x10ec0225 :case 0x10ec0295 : + spec->codec_variant =ALC269_TYPE_ALC225 ; +break ;case 0x10ec0299 : spec->codec_variant =ALC269_TYPE_ALC225 ; + spec->gen.mixer_nid =0 ;/* no loopback on ALC299 */ break ;case 0x10ec0234 :case 0x10ec0274 :
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 62/98 x86/power: Fix some ordering bugs in __restore_processor_context()
In reply to Sasha LevinFrom: Andy Lutomirski <[email protected]>
[ Upstream commit 5b06bbcfc2c621da3009da8decb7511500c293ed ]
__restore_processor_context() had a couple of ordering bugs. It restored GSBASE after calling load_gs_index(), and the latter can call into tracing code. It also tried to restore segment registers before restoring the LDT, which is straight-up wrong.
Reorder the code so that we restore GSBASE, then the descriptor tables, then the segments.
This fixes two bugs. First, it fixes a regression that broke resume under certain configurations due to irqflag tracing in native_load_gs_index(). Second, it fixes resume when the userspace process that initiated suspect had funny segments. The latter can be reproduced by compiling this:
// SPDX-License-Identifier: GPL-2.0
/*
* ldt_echo.c - Echo argv[1] while using an LDT segment */
int main(int argc, char **argv)
{
int ret;
size_t len;
char *buf;
const struct user_desc desc = {
.entry_number = 0,
.base_addr = 0,
.limit = 0xfffff,
.seg_32bit = 1,
.contents = 0, /* Data, grow-up */
.read_exec_only = 0,
.limit_in_pages = 1,
.seg_not_present = 0,
.useable = 0
};
if (argc != 2)
errx(1, "Usage: %s STRING", argv[0]);
len = asprintf(&buf, "%s\n", argv[1]);
if (len < 0)
errx(1, "Out of memory");
ret = syscall(SYS_modify_ldt, 1, &desc, sizeof(desc));
if (ret < -1)
errno = -ret;
if (ret)
err(1, "modify_ldt");
asm volatile ("movw %0, %%es" :: "rm" ((unsigned short)7));
write(1, buf, len);
return 0;
}and running ldt_echo >/sys/power/mem
Without the fix, the latter causes a triple fault on resume.
--- arch/x86/power/cpu.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
arch/x86/power/cpu.c +17 -4
@@ -222,8 +222,20 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)load_idt ((const struct desc_ptr *)&ctxt->idt_limit);#endif +#ifdef CONFIG_X86_64 /* -* segment registers +* We need GSBASE restored before percpu access can work. +* percpu access can happen in exception handlers or in complicated +* helpers like load_gs_index(). +*/ +wrmsrl (MSR_GS_BASE , ctxt->gs_base); +#endif + +fix_processor_context (); + +/* +* Restore segment registers. This happens after restoring the GDT +* and LDT, which happen in fix_processor_context(). */ #ifdef CONFIG_X86_32 loadsegment (es, ctxt->es);
@@ -244,13 +256,14 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)load_gs_index (ctxt->gs); asmvolatile ("movw %0, %%ss" ::"r" (ctxt->ss)); +/* +* Restore FSBASE and user GSBASE after reloading the respective +* segment selectors. +*/ wrmsrl (MSR_FS_BASE , ctxt->fs_base); -wrmsrl (MSR_GS_BASE , ctxt->gs_base);wrmsrl (MSR_KERNEL_GS_BASE , ctxt->gs_kernel_base);#endif -fix_processor_context (); -do_fpu_end (); x86_platform.restore_sched_clock_state ();mtrr_bp_restore ();
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 63/98 ath10k: convert warning about non-existent OTP board id to debug message
In reply to Sasha LevinFrom: Kalle Valo <[email protected]>
[ Upstream commit 7be52c03bbf7c8f53211ed13810d64dcb2bc7168 ]
Currently ath10k unncessarily warns about board id not available from OTP:
ath10k_pci 0000:02:00.0: pci irq msi oper_irq_mode 2 irq_mode 0 reset_mode 0 ath10k_pci 0000:02:00.0: qca988x hw2.0 target 0x4100016c chip_id 0x043202ff sub 0000:0000 ath10k_pci 0000:02:00.0: kconfig debug 1 debugfs 1 tracing 1 dfs 1 testmode 1 ath10k_pci 0000:02:00.0: firmware ver 10.2.4.70.9-2 api 5 features no-p2p,raw-mode crc32 b8d50af5 ath10k_pci 0000:02:00.0: board id is not exist in otp, ignore itath10k_pci 0000:02:00.0: board_file api 1 bmi_id N/A crc32 bebc7c08ath10k_pci 0000:02:00.0: htt-ver 2.1 wmi-op 5 htt-op 2 cal otp max-sta 128 raw 0 hwcrypto 1
But not all boards have the board id in OTP so this is not a problem and no need to confuse the user with that info. So this can be safely changed to a debug message.
Also fix grammar in the debug message.
--- drivers/net/wireless/ath/ath10k/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath10k/core.c +2 -1
@@ -698,7 +698,8 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)if ((result &ATH10K_BMI_BOARD_ID_STATUS_MASK ) !=0 || (board_id ==0 )) { -ath10k_warn (ar,"board id is not exist in otp, ignore it\n" ); +ath10k_dbg (ar,ATH10K_DBG_BOOT , +"board id does not exist in otp, ignore it\n" );return -EOPNOTSUPP ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 64/98 ipv6: fix cleanup ordering for ip6_mr failure
In reply to Sasha LevinFrom: Sabrina Dubroca <[email protected]>
[ Upstream commit afe49de44c27a89e8e9631c44b5ffadf6ace65e2 ]
Commit 15e668070a64 ("ipv6: reorder icmpv6_init() and ip6_mr_init()") moved the cleanup label for ipmr_fail, but should have changed the contents of the cleanup labels as well. Now we can end up cleaning up icmpv6 even though it hasn't been initialized (jump to icmp_fail or ipmr_fail).
Simply undo things in the reverse order of their initialization.
Example of panic (triggered by faking a failure of icmpv6_init):
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN PTI
[...]
RIP: 0010:__list_del_entry_valid+0x79/0x160
[...]
Call Trace:
? lock_release+0x8a0/0x8a0
unregister_pernet_operations+0xd4/0x560
? ops_free_list+0x480/0x480
? down_write+0x91/0x130
? unregister_pernet_subsys+0x15/0x30
? down_read+0x1b0/0x1b0
? up_read+0x110/0x110
? kmem_cache_create_usercopy+0x1b4/0x240
unregister_pernet_subsys+0x1d/0x30
icmpv6_cleanup+0x1d/0x30
inet6_init+0x1b5/0x23f--- net/ipv6/af_inet6.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/ipv6/af_inet6.c +3 -3
@@ -1045,11 +1045,11 @@ static int __init inet6_init(void) igmp_fail:ndisc_cleanup (); ndisc_fail: -ip6_mr_cleanup (); +icmpv6_cleanup (); icmp_fail: -unregister_pernet_subsys (&inet6_net_ops); +ip6_mr_cleanup (); ipmr_fail: -icmpv6_cleanup (); +unregister_pernet_subsys (&inet6_net_ops); register_pernet_fail:sock_unregister (PF_INET6 );rtnl_unregister_all (PF_INET6 );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 65/98 IB/ipoib: Fix lockdep issue found on ipoib_ib_dev_heavy_flush
In reply to Sasha LevinFrom: Alex Vesker <[email protected]>
[ Upstream commit 1f80bd6a6cc8358b81194e1f5fc16449947396ec ]
The locking order of vlan_rwsem (LOCK A) and then rtnl (LOCK B), contradicts other flows such as ipoib_open possibly causing a deadlock. To prevent this deadlock heavy flush is called with RTNL locked and only then tries to acquire vlan_rwsem.
This deadlock is possible only when there are child interfaces.
[ 140.941758] ======================================================
[ 140.946276] WARNING: possible circular locking dependency detected
[ 140.950950] 4.15.0-rc1+ #9 Tainted: G O
[ 140.954797] ------------------------------------------------------
[ 140.959424] kworker/u32:1/146 is trying to acquire lock:
[ 140.963450] (rtnl_mutex){+.+.}, at: [<ffffffffc083516a>] __ipoib_ib_dev_flush+0x2da/0x4e0 [ib_ipoib]
[ 140.970006]
but task is already holding lock:
[ 140.975141] (&priv->vlan_rwsem){++++}, at: [<ffffffffc0834ee1>] __ipoib_ib_dev_flush+0x51/0x4e0 [ib_ipoib]
[ 140.982105]
which lock already depends on the new lock.
[ 140.990023]
the existing dependency chain (in reverse order) is:
[ 140.998650]
-> #1 (&priv->vlan_rwsem){++++}:
[ 141.005276] down_read+0x4d/0xb0
[ 141.009560] ipoib_open+0xad/0x120 [ib_ipoib]
[ 141.014400] __dev_open+0xcb/0x140
[ 141.017919] __dev_change_flags+0x1a4/0x1e0
[ 141.022133] dev_change_flags+0x23/0x60
[ 141.025695] devinet_ioctl+0x704/0x7d0
[ 141.029156] sock_do_ioctl+0x20/0x50
[ 141.032526] sock_ioctl+0x221/0x300
[ 141.036079] do_vfs_ioctl+0xa6/0x6d0
[ 141.039656] SyS_ioctl+0x74/0x80
[ 141.042811] entry_SYSCALL_64_fastpath+0x1f/0x96
[ 141.046891]
-> #0 (rtnl_mutex){+.+.}:
[ 141.051701] lock_acquire+0xd4/0x220
[ 141.055212] __mutex_lock+0x88/0x970
[ 141.058631] __ipoib_ib_dev_flush+0x2da/0x4e0 [ib_ipoib]
[ 141.063160] __ipoib_ib_dev_flush+0x71/0x4e0 [ib_ipoib]
[ 141.067648] process_one_work+0x1f5/0x610
[ 141.071429] worker_thread+0x4a/0x3f0
[ 141.074890] kthread+0x141/0x180
[ 141.078085] ret_from_fork+0x24/0x30
[ 141.081559]other info that might help us debug this:
[ 141.088967] Possible unsafe locking scenario: [ 141.094280] CPU0 CPU1 [ 141.097953] ---- ---- [ 141.101640] lock(&priv->vlan_rwsem); [ 141.104771] lock(rtnl_mutex); [ 141.109207] lock(&priv->vlan_rwsem); [ 141.114032] lock(rtnl_mutex); [ 141.116800] *** DEADLOCK ***
--- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/infiniband/ulp/ipoib/ipoib_ib.c +3 -4
@@ -1190,13 +1190,10 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,ipoib_ib_dev_down (dev);if (level ==IPOIB_FLUSH_HEAVY ) { -rtnl_lock ();if (test_bit (IPOIB_FLAG_INITIALIZED , &priv->flags))ipoib_ib_dev_stop (dev); - result =ipoib_ib_dev_open (dev); -rtnl_unlock (); -if (result) +if (ipoib_ib_dev_open (dev))return ;if (netif_queue_stopped (dev))
@@ -1236,7 +1233,9 @@ void ipoib_ib_dev_flush_heavy(struct work_struct *work)struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv, flush_heavy); +rtnl_lock ();__ipoib_ib_dev_flush (priv,IPOIB_FLUSH_HEAVY ,0 ); +rtnl_unlock (); }void ipoib_ib_dev_cleanup (struct net_device *dev)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 66/98 IB/rxe: put the pool on allocation failure
In reply to Sasha LevinFrom: Doug Ledford <[email protected]>
[ Upstream commit 6b9f8970cd30929cb6b372fa44fa66da9e59c650 ]
If the allocation of elem fails, it is not sufficient to simply check for NULL and return. We need to also put our reference on the pool or else we will leave the pool with a permanent ref count and we will never be able to free it.
--- drivers/infiniband/sw/rxe/rxe_pool.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/infiniband/sw/rxe/rxe_pool.c +9 -7
@@ -402,23 +402,25 @@ void *rxe_alloc(struct rxe_pool *pool)kref_get (&pool->rxe->ref_cnt); -if (atomic_inc_return (&pool->num_elem) > pool->max_elem) { -atomic_dec (&pool->num_elem); -rxe_dev_put (pool->rxe); -rxe_pool_put (pool); -return NULL ; - } +if (atomic_inc_return (&pool->num_elem) > pool->max_elem) + goto out_put_pool; elem =kmem_cache_zalloc (pool_cache (pool), (pool->flags &RXE_POOL_ATOMIC ) ?GFP_ATOMIC :GFP_KERNEL );if (!elem) -return NULL ; + goto out_put_pool; elem->pool = pool;kref_init (&elem->ref_cnt);return elem; + +out_put_pool: +atomic_dec (&pool->num_elem); +rxe_dev_put (pool->rxe); +rxe_pool_put (pool); +return NULL ; }void rxe_elem_release (struct kref *kref)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 67/98 nbd: only set MSG_MORE when we have more to send
In reply to Sasha LevinFrom: Josef Bacik <[email protected]>
[ Upstream commit d61b7f972dab2a7d187c38254845546dfc8eed85 ]
A user noticed that write performance was horrible over loopback and we traced it to an inversion of when we need to set MSG_MORE. It should be set when we have more bvec's to send, not when we are on the last bvec. This patch made the test go from 20 iops to 78k iops.
--- drivers/block/nbd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/block/nbd.c +2 -4
@@ -269,7 +269,7 @@ static inline int sock_send_bvec(struct nbd_device *nbd, struct bio_vec *bvec,static int nbd_send_cmd (struct nbd_device *nbd,struct nbd_cmd *cmd) {struct request *req =blk_mq_rq_from_pdu (cmd); -int result, flags; +int result;struct nbd_request request;unsigned long size =blk_rq_bytes (req);struct bio *bio;
@@ -309,7 +309,6 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd)if (type !=NBD_CMD_WRITE )return 0 ; - flags =0 ; bio = req->bio;while (bio) {struct bio *next = bio->bi_next;
@@ -318,9 +317,8 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd)bio_for_each_segment (bvec, bio, iter) {bool is_last = !next &&bio_iter_last (bvec, iter); +int flags = is_last ?0 :MSG_MORE ; -if (is_last) - flags =MSG_MORE ;dev_dbg (nbd_to_dev (nbd),"request %p: sending %d bytes data\n" , cmd, bvec.bv_len); result =sock_send_bvec (nbd, &bvec, flags);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 68/98 mm/frame_vector.c: release a semaphore in 'get_vaddr_frames()'
In reply to Sasha LevinFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 1f704fd0d14043e76e80f6b8b2251b9b2cedcca6 ]
A semaphore is acquired before this check, so we must release it before leaving.
--- mm/frame_vector.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
mm/frame_vector.c +4 -2
@@ -61,8 +61,10 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,* get_user_pages_longterm() and disallow it for filesystem-dax * mappings. */ -if (vma_is_fsdax (vma)) -return -EOPNOTSUPP ; +if (vma_is_fsdax (vma)) { + ret = -EOPNOTSUPP ; + goto out; + }if (!(vma->vm_flags & (VM_IO |VM_PFNMAP ))) { vec->got_ref = true;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 69/98 IB/mlx5: Avoid passing an invalid QP type to firmware
In reply to Sasha LevinFrom: Noa Osherovich <[email protected]>
[ Upstream commit e7b169f34403becd3c9fd3b6e46614ab788f2187 ]
During QP creation, the mlx5 driver translates the QP type to an internal value which is passed on to FW. There was no check to make sure that the translated value is valid, and -EINVAL was coerced into the mailbox command.
Current firmware refuses this as an invalid QP type, but future/past firmware may do something else.
--- drivers/infiniband/hw/mlx5/qp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/qp.c +6 -1
@@ -1523,6 +1523,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,u32 uidx =MLX5_IB_DEFAULT_UIDX ;struct mlx5_ib_create_qp ucmd;struct mlx5_ib_qp_base *base; +int mlx5_st;void *qpc;u32 *in;int err;
@@ -1538,6 +1539,10 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,spin_lock_init (&qp->sq.lock);spin_lock_init (&qp->rq.lock); + mlx5_st =to_mlx5_st (init_attr->qp_type); +if (mlx5_st <0 ) +return -EINVAL ; +if (init_attr->rwq_ind_tbl) {if (!udata)return -ENOSYS ;
@@ -1665,7 +1670,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, qpc =MLX5_ADDR_OF (create_qp_in, in, qpc); -MLX5_SET (qpc, qpc, st,to_mlx5_st (init_attr->qp_type)); +MLX5_SET (qpc, qpc, st, mlx5_st);MLX5_SET (qpc, qpc, pm_state,MLX5_QP_PM_MIGRATED );if (init_attr->qp_type !=MLX5_IB_QPT_REG_UMR )
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 70/98 scsi: qla2xxx: Avoid double completion of abort command
In reply to Sasha LevinFrom: Ben Hutchings <[email protected]>
[ Upstream commit 3a9910d7b686546dcc9986e790af17e148f1c888 ]
qla2x00_tmf_sp_done() now deletes the timer that will run qla2x00_tmf_iocb_timeout(), but doesn't check whether the timer already expired. Check the return value from del_timer() to avoid calling complete() a second time.
--- drivers/scsi/qla2xxx/qla_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/qla2xxx/qla_init.c +2 -2
@@ -368,8 +368,8 @@ qla24xx_abort_sp_done(void *data, void *ptr, int res)srb_t *sp = (srb_t *)ptr;struct srb_iocb *abt = &sp->u.iocb_cmd; -del_timer (&sp->u.iocb_cmd.timer); -complete (&abt->u.abt.comp); +if (del_timer (&sp->u.iocb_cmd.timer)) +complete (&abt->u.abt.comp); } static int
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 71/98 drm: bochs: Don't remove uninitialized fbdev framebuffer
In reply to Sasha LevinFrom: Gabriel Krisman Bertazi <[email protected]>
[ Upstream commit 4fa13dbe8c86382a846584e65c47bce09297f75b ]
In the same spirit of the fix for QXL in commit 861078381ba5 ("drm: qxl:
Don't alloc fbdev if emulation is not supported"), prevent the Oops in the unbind path of Bochs if fbdev emulation is disabled.
[ 112.176009] Oops: 0002 [#1] SMP [ 112.176009] Modules linked in: bochs_drm [ 112.176009] CPU: 0 PID: 3002 Comm: bash Not tainted 4.11.0-rc1+ #111 [ 112.176009] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-20161025_171302-gandalf 04/01/2014 [ 112.176009] task: ffff8800743bbac0 task.stack: ffffc90000b5c000 [ 112.176009] RIP: 0010:mutex_lock+0x18/0x30 [ 112.176009] RSP: 0018:ffffc90000b5fc78 EFLAGS: 00010246 [ 112.176009] RAX: 0000000000000000 RBX: 0000000000000260 RCX: 0000000000000000 [ 112.176009] RDX: ffff8800743bbac0 RSI: ffff8800787176e0 RDI: 0000000000000260 [ 112.176009] RBP: ffffc90000b5fc80 R08: ffffffff00000000 R09: 00000000ffffffff [ 112.176009] R10: ffff88007b463650 R11: 0000000000000000 R12: 0000000000000260 [ 112.176009] R13: ffff8800787176e0 R14: ffffffffa0003068 R15: 0000000000000060 [ 112.176009] FS: 00007f20564c7b40(0000) GS:ffff88007ce00000(0000) knlGS:0000000000000000 [ 112.176009] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 112.176009] CR2: 0000000000000260 CR3: 000000006b89c000 CR4: 00000000000006f0 [ 112.176009] Call Trace: [ 112.176009] drm_mode_object_unregister+0x1e/0x50 [ 112.176009] drm_framebuffer_unregister_private+0x15/0x20 [ 112.176009] bochs_fbdev_fini+0x57/0x70 [bochs_drm] [ 112.176009] bochs_unload+0x16/0x50 [bochs_drm] [ 112.176009] drm_dev_unregister+0x37/0xd0 [ 112.176009] drm_put_dev+0x31/0x60 [ 112.176009] bochs_pci_remove+0x10/0x20 [bochs_drm] [ 112.176009] pci_device_remove+0x34/0xb0 [ 112.176009] device_release_driver_internal+0x150/0x200 [ 112.176009] device_release_driver+0xd/0x10 [ 112.176009] unbind_store+0x108/0x150 [ 112.176009] drv_attr_store+0x20/0x30 [ 112.176009] sysfs_kf_write+0x32/0x40 [ 112.176009] kernfs_fop_write+0x10b/0x190 [ 112.176009] __vfs_write+0x23/0x120 [ 112.176009] ? security_file_permission+0x36/0xb0 [ 112.176009] ? rw_verify_area+0x49/0xb0 [ 112.176009] vfs_write+0xb0/0x190 [ 112.176009] SyS_write+0x41/0xa0 [ 112.176009] entry_SYSCALL_64_fastpath+0x1a/0xa9 [ 112.176009] RIP: 0033:0x7f2055bd5620 [ 112.176009] RSP: 002b:00007ffed2f487d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 112.176009] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f2055bd5620 [ 112.176009] RDX: 000000000000000d RSI: 0000000000ee0008 RDI: 0000000000000001 [ 112.176009] RBP: 0000000000000001 R08: 00007f2055e94760 R09: 00007f20564c7b40 [ 112.176009] R10: 0000000000000073 R11: 0000000000000246 R12: 0000000000000000 [ 112.176009] R13: 00007ffed2f48d70 R14: 0000000000000000 R15: 0000000000000000 [ 112.176009] Code: 00 00 00 55 be 02 00 00 00 48 89 e5 e8 62 fb ff ff 5d c3 55 48 89 e5 53 48 89 fb e8 53 e9 ff ff 65 48 8b 14 25 40 c4 00 00 31 c0 <f0> 48 0f b1 13 48 85 c0 74 08 48 89 df e8c6 ff ff ff 5b 5d c3 [ 112.176009] RIP: mutex_lock+0x18/0x30 RSP: ffffc90000b5fc78 [ 112.176009] CR2: 0000000000000260 [ 112.205622] ---[ end trace 76189cd7a9bdd155 ]---
--- drivers/gpu/drm/bochs/bochs_fbdev.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/gpu/drm/bochs/bochs_fbdev.c +4 -5
@@ -138,6 +138,7 @@ static int bochsfb_create(struct drm_fb_helper *helper, info->fix.smem_start =0 ; info->fix.smem_len = size; + bochs->fb.initialized = true;return 0 ; }
@@ -155,7 +156,6 @@ static int bochs_fbdev_destroy(struct bochs_device *bochs) gfb->obj =NULL ; } -drm_fb_helper_fini (&bochs->fb.helper);drm_framebuffer_unregister_private (&gfb->base);drm_framebuffer_cleanup (&gfb->base);
@@ -188,7 +188,6 @@ int bochs_fbdev_init(struct bochs_device *bochs)if (ret) goto fini; - bochs->fb.initialized = true;return 0 ; fini:
@@ -198,9 +197,9 @@ int bochs_fbdev_init(struct bochs_device *bochs)void bochs_fbdev_fini (struct bochs_device *bochs) { -if (!bochs->fb.initialized) -return ; +if (bochs->fb.initialized) +bochs_fbdev_destroy (bochs); -bochs_fbdev_destroy (bochs); +drm_fb_helper_fini (&bochs->fb.helper); bochs->fb.initialized = false; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 72/98 i40e: avoid NVM acquire deadlock during NVM update
In reply to Sasha LevinFrom: Anjali Singhai Jain <[email protected]>
[ Upstream commit 09f79fd49d94cda5837e9bfd0cb222232b3b6d9f ]
X722 devices use the AdminQ to access the NVM, and this requires taking the AdminQ lock. Because of this, we lock the AdminQ during i40e_read_nvm(), which is also called in places where the lock is already held, such as the firmware update path which wants to lock once and then unlock when finished after performing several tasks.
Although this should have only affected X722 devices, commit 96a39aed25e6 ("i40e: Acquire NVM lock before reads on all devices", 2016-12-02) added locking for all NVM reads, regardless of device family.
This resulted in us accidentally causing NVM acquire timeouts on all devices, causing failed firmware updates which left the eeprom in a corrupt state.
Create unsafe non-locked variants of i40e_read_nvm_word and i40e_read_nvm_buffer, __i40e_read_nvm_word and __i40e_read_nvm_buffer respectively. These variants will not take the NVM lock and are expected to only be called in places where the NVM lock is already held if needed.
Since the only caller of i40e_read_nvm_buffer() was in such a path, remove it entirely in favor of the unsafe version. If necessary we can always add it back in the future.
Additionally, we now need to hold the NVM lock in i40e_validate_checksum because the call to i40e_calc_nvm_checksum now assumes that the NVM lock is held. We can further move the call to read I40E_SR_SW_CHECKSUM_WORD up a bit so that we do not need to acquire the NVM lock twice.
This should resolve firmware updates and also fix potential raise that could have caused the driver to report an invalid NVM checksum upon driver load.
--- drivers/net/ethernet/intel/i40e/i40e_nvm.c | 98 ++++++++++++------- .../net/ethernet/intel/i40e/i40e_prototype.h | 2 - 2 files changed, 60 insertions(+), 40 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_nvm.c +60 -38
@@ -266,7 +266,7 @@ static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) * @data: word read from the Shadow RAM * -* Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. +* Reads one 16 bit word from the Shadow RAM using the AdminQ **/ static i40e_status i40e_read_nvm_word_aq (struct i40e_hw *hw,u16 offset,u16 *data)
@@ -280,27 +280,49 @@ static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset, }/** -* i40e_read_nvm_word - Reads Shadow RAM +* __i40e_read_nvm_word - Reads nvm word, assumes called does the locking * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) * @data: word read from the Shadow RAM * -* Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register. +* Reads one 16 bit word from the Shadow RAM. +* +* Do not use this function except in cases where the nvm lock is already +* taken via i40e_acquire_nvm(). +**/ +static i40e_status __i40e_read_nvm_word (struct i40e_hw *hw, +u16 offset,u16 *data) +{ +i40e_status ret_code =0 ; + +if (hw->flags &I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE ) + ret_code =i40e_read_nvm_word_aq (hw, offset, data); +else + ret_code =i40e_read_nvm_word_srctl (hw, offset, data); +return ret_code; +} + +/** +* i40e_read_nvm_word - Reads nvm word and acquire lock if necessary +* @hw: pointer to the HW structure +* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) +* @data: word read from the Shadow RAM +* +* Reads one 16 bit word from the Shadow RAM. **/ i40e_status i40e_read_nvm_word (struct i40e_hw *hw,u16 offset,u16 *data) { -enum i40e_status_code ret_code =0 ; +i40e_status ret_code =0 ; ret_code =i40e_acquire_nvm (hw,I40E_RESOURCE_READ ); -if (!ret_code) { -if (hw->flags &I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE ) { - ret_code =i40e_read_nvm_word_aq (hw, offset, data); - }else { - ret_code =i40e_read_nvm_word_srctl (hw, offset, data); - } -i40e_release_nvm (hw); - } +if (ret_code) +return ret_code; + + ret_code =__i40e_read_nvm_word (hw, offset, data); + +i40e_release_nvm (hw); +return ret_code; }
@@ -393,31 +415,25 @@ static i40e_status i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset, }/** -* i40e_read_nvm_buffer - Reads Shadow RAM buffer +* __i40e_read_nvm_buffer - Reads nvm buffer, caller must acquire lock * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). * @words: (in) number of words to read; (out) number of words actually read * @data: words read from the Shadow RAM * * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() -* method. The buffer read is preceded by the NVM ownership take -* and followed by the release. +* method. **/ -i40e_status i40e_read_nvm_buffer (struct i40e_hw *hw,u16 offset, -u16 *words,u16 *data) +static i40e_status __i40e_read_nvm_buffer (struct i40e_hw *hw, +u16 offset,u16 *words, +u16 *data) { -enum i40e_status_code ret_code =0 ; +i40e_status ret_code =0 ; -if (hw->flags &I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE ) { - ret_code =i40e_acquire_nvm (hw,I40E_RESOURCE_READ ); -if (!ret_code) { - ret_code =i40e_read_nvm_buffer_aq (hw, offset, words, - data); -i40e_release_nvm (hw); - } - }else { +if (hw->flags &I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE ) + ret_code =i40e_read_nvm_buffer_aq (hw, offset, words, data); +else ret_code =i40e_read_nvm_buffer_srctl (hw, offset, words, data); - }return ret_code; }
@@ -499,15 +515,15 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw, data = (u16 *)vmem.va;/* read pointer to VPD area */ - ret_code =i40e_read_nvm_word (hw,I40E_SR_VPD_PTR , &vpd_module); + ret_code =__i40e_read_nvm_word (hw,I40E_SR_VPD_PTR , &vpd_module);if (ret_code) { ret_code =I40E_ERR_NVM_CHECKSUM ; goto i40e_calc_nvm_checksum_exit; }/* read pointer to PCIe Alt Auto-load module */ - ret_code =i40e_read_nvm_word (hw,I40E_SR_PCIE_ALT_AUTO_LOAD_PTR , - &pcie_alt_module); + ret_code =__i40e_read_nvm_word (hw,I40E_SR_PCIE_ALT_AUTO_LOAD_PTR , + &pcie_alt_module);if (ret_code) { ret_code =I40E_ERR_NVM_CHECKSUM ; goto i40e_calc_nvm_checksum_exit;
@@ -521,7 +537,7 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,if ((i %I40E_SR_SECTOR_SIZE_IN_WORDS ) ==0 ) {u16 words =I40E_SR_SECTOR_SIZE_IN_WORDS ; - ret_code =i40e_read_nvm_buffer (hw, i, &words, data); + ret_code =__i40e_read_nvm_buffer (hw, i, &words, data);if (ret_code) { ret_code =I40E_ERR_NVM_CHECKSUM ; goto i40e_calc_nvm_checksum_exit;
@@ -593,14 +609,19 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,u16 checksum_sr =0 ;u16 checksum_local =0 ; +/* We must acquire the NVM lock in order to correctly synchronize the +* NVM accesses across multiple PFs. Without doing so it is possible +* for one of the PFs to read invalid data potentially indicating that +* the checksum is invalid. +*/ + ret_code =i40e_acquire_nvm (hw,I40E_RESOURCE_READ ); +if (ret_code) +return ret_code; ret_code =i40e_calc_nvm_checksum (hw, &checksum_local); +__i40e_read_nvm_word (hw,I40E_SR_SW_CHECKSUM_WORD , &checksum_sr); +i40e_release_nvm (hw);if (ret_code) - goto i40e_validate_nvm_checksum_exit; - -/* Do not use i40e_read_nvm_word() because we do not want to take -* the synchronization semaphores twice here. -*/ -i40e_read_nvm_word (hw,I40E_SR_SW_CHECKSUM_WORD , &checksum_sr); +return ret_code;/* Verify read checksum from EEPROM is the same as * calculated checksum
@@ -612,7 +633,6 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,if (checksum) *checksum = checksum_local; -i40e_validate_nvm_checksum_exit:return ret_code; }
@@ -986,6 +1006,7 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,break ;case I40E_NVMUPD_CSUM_CON : +/* Assumes the caller has acquired the nvm */ status =i40e_update_nvm_checksum (hw);if (status) { *perrno = hw->aq.asq_last_status ?
@@ -1000,6 +1021,7 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,break ;case I40E_NVMUPD_CSUM_LCB : +/* Assumes the caller has acquired the nvm */ status =i40e_update_nvm_checksum (hw);if (status) { *perrno = hw->aq.asq_last_status ?
drivers/net/ethernet/intel/i40e/i40e_prototype.h +0 -2
@@ -311,8 +311,6 @@ i40e_status i40e_acquire_nvm(struct i40e_hw *hw,void i40e_release_nvm (struct i40e_hw *hw);i40e_status i40e_read_nvm_word (struct i40e_hw *hw,u16 offset,u16 *data); -i40e_status i40e_read_nvm_buffer (struct i40e_hw *hw,u16 offset, -u16 *words,u16 *data);i40e_status i40e_update_nvm_checksum (struct i40e_hw *hw);i40e_status i40e_validate_nvm_checksum (struct i40e_hw *hw,u16 *checksum);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 73/98 Revert "IB/ipoib: Update broadcast object if PKey value was changed in index 0"
In reply to Sasha LevinFrom: Alex Estrin <[email protected]>
[ Upstream commit 612601d0013f03de9dc134809f242ba6da9ca252 ]
commit 9a9b8112699d will cause core to fail UD QP from being destroyed on ipoib unload, therefore cause resources leakage.
On pkey change event above patch modifies mgid before calling underlying driver to detach it from QP. Drivers' detach_mcast() will fail to find modified mgid it was never given to attach in a first place. Core qp->usecnt will never go down, so ib_destroy_qp() will fail.
IPoIB driver actually does take care of new broadcast mgid based on new pkey by destroying an old mcast object in ipoib_mcast_dev_flush())
....
if (priv->broadcast) {
rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree);
list_add_tail(&priv->broadcast->list, &remove_list);
priv->broadcast = NULL;
}...
then in restarted ipoib_macst_join_task() creating a new broadcast mcast object, sending join request and on completion tells the driver to attach to reinitialized QP:
...
if (!priv->broadcast) {
...
broadcast = ipoib_mcast_alloc(dev, 0); ... memcpy(broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4, sizeof (union ib_gid)); priv->broadcast = broadcast;
...
--- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 13 ------------- 1 file changed, 13 deletions(-)
drivers/infiniband/ulp/ipoib/ipoib_ib.c +0 -13
@@ -974,19 +974,6 @@ static inline int update_parent_pkey(struct ipoib_dev_priv *priv)*/ priv->dev->broadcast[8 ] = priv->pkey >>8 ; priv->dev->broadcast[9 ] = priv->pkey &0xff ; - -/* -* Update the broadcast address in the priv->broadcast object, -* in case it already exists, otherwise no one will do that. -*/ -if (priv->broadcast) { -spin_lock_irq (&priv->lock); -memcpy (priv->broadcast->mcmember.mgid.raw, - priv->dev->broadcast +4 , -sizeof (union ib_gid )); -spin_unlock_irq (&priv->lock); - } -return 0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 74/98 Btrfs: incremental send, fix invalid memory access
In reply to Sasha LevinFrom: Filipe Manana <[email protected]>
[ Upstream commit 24e52b11e0ca788513b945a87b57cc0522a92933 ]
When doing an incremental send, while processing an extent that changed between the parent and send snapshots and that extent was an inline extent in the parent snapshot, it's possible to access a memory region beyond the end of leaf if the inline extent is very small and it is the first item in a leaf.
An example scenario is described below.
The send snapshot has the following leaf:
leaf 33865728 items 33 free space 773 generation 46 owner 5 fs uuid ab7090d8-dafd-4fb9-9246-723b6d2e2fb7 chunk uuid 2d16478c-c704-4ab9-b574-68bff2281b1f
(...)
item 14 key (335 EXTENT_DATA 0) itemoff 3052 itemsize 53
generation 36 type 1 (regular)
extent data disk byte 12791808 nr 4096
extent data offset 0 nr 4096 ram 4096
extent compression 0 (none)
item 15 key (335 EXTENT_DATA 8192) itemoff 2999 itemsize 53
generation 36 type 1 (regular)
extent data disk byte 138170368 nr 225280
extent data offset 0 nr 225280 ram 225280
extent compression 0 (none)
(...)And the parent snapshot has the following leaf:
leaf 31272960 items 17 free space 17 generation 31 owner 5
fs uuid ab7090d8-dafd-4fb9-9246-723b6d2e2fb7
chunk uuid 2d16478c-c704-4ab9-b574-68bff2281b1f
item 0 key (335 EXTENT_DATA 0) itemoff 3951 itemsize 44
generation 31 type 0 (inline)
inline extent data size 23 ram_bytes 613 compression 1 (zlib)
(...)
When computing the send stream, it is detected that the extent of inode 335, at file offset 0, and at fs/btrfs/send.c:is_extent_unchanged() we grab the leaf from the parent snapshot and access the inline extent item. However, before jumping to the 'out' label, we access the 'offset' and 'disk_bytenr' fields of the extent item, which should not be done for inline extents since the inlined data starts at the offset of the 'disk_bytenr' field and can be very small. For example accessing the 'offset' field of the file extent item results in the following trace:
[ 599.705368] general protection fault: 0000 [#1] PREEMPT SMP [ 599.706296] Modules linked in: btrfs psmouse i2c_piix4 ppdev acpi_cpufreq serio_raw parport_pc i2c_core evdev tpm_tis tpm_tis_core sg pcspkr parport tpm button su$ [ 599.709340] CPU: 7 PID: 5283 Comm: btrfs Not tainted 4.10.0-rc8-btrfs-next-46+ #1 [ 599.709340] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.1-0-gb3ef39f-prebuilt.qemu-project.org 04/01/2014 [ 599.709340] task: ffff88023eedd040 task.stack: ffffc90006658000 [ 599.709340] RIP: 0010:read_extent_buffer+0xdb/0xf4 [btrfs] [ 599.709340] RSP: 0018:ffffc9000665ba00 EFLAGS: 00010286 [ 599.709340] RAX: db73880000000000 RBX: 0000000000000000 RCX: 0000000000000001 [ 599.709340] RDX: ffffc9000665ba60 RSI: db73880000000000 RDI: ffffc9000665ba5f [ 599.709340] RBP: ffffc9000665ba30 R08: 0000000000000001 R09: ffff88020dc5e098 [ 599.709340] R10: 0000000000001000 R11: 0000160000000000 R12: 6db6db6db6db6db7 [ 599.709340] R13: ffff880000000000 R14: 0000000000000000 R15: ffff88020dc5e088 [ 599.709340] FS: 00007f519555a8c0(0000) GS:ffff88023f3c0000(0000) knlGS:0000000000000000 [ 599.709340] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 599.709340] CR2: 00007f1411afd000 CR3: 0000000235f8e000 CR4: 00000000000006e0 [ 599.709340] Call Trace: [ 599.709340] btrfs_get_token_64+0x93/0xce [btrfs] [ 599.709340] ? printk+0x48/0x50 [ 599.709340] btrfs_get_64+0xb/0xd [btrfs] [ 599.709340] process_extent+0x3a1/0x1106 [btrfs] [ 599.709340] ? btree_read_extent_buffer_pages+0x5/0xef [btrfs] [ 599.709340] changed_cb+0xb03/0xb3d [btrfs] [ 599.709340] ? btrfs_get_token_32+0x7a/0xcc [btrfs] [ 599.709340] btrfs_compare_trees+0x432/0x53d [btrfs] [ 599.709340] ? process_extent+0x1106/0x1106 [btrfs] [ 599.709340] btrfs_ioctl_send+0x960/0xe26 [btrfs] [ 599.709340] btrfs_ioctl+0x181b/0x1fed [btrfs] [ 599.709340] ? trace_hardirqs_on_caller+0x150/0x1ac [ 599.709340] vfs_ioctl+0x21/0x38 [ 599.709340] ? vfs_ioctl+0x21/0x38 [ 599.709340] do_vfs_ioctl+0x611/0x645 [ 599.709340] ? rcu_read_unlock+0x5b/0x5d [ 599.709340] ? __fget+0x6d/0x79 [ 599.709340] SyS_ioctl+0x57/0x7b [ 599.709340] entry_SYSCALL_64_fastpath+0x18/0xad [ 599.709340] RIP: 0033:0x7f51945eec47 [ 599.709340] RSP: 002b:00007ffc21c13e98 EFLAGS: 00000202 ORIG_RAX: 0000000000000010 [ 599.709340] RAX: ffffffffffffffda RBX: ffffffff81096459 RCX: 00007f51945eec47 [ 599.709340] RDX: 00007ffc21c13f20 RSI: 0000000040489426 RDI: 0000000000000004 [ 599.709340] RBP: ffffc9000665bf98 R08: 00007f519450d700 R09: 00007f519450d700 [ 599.709340] R10: 00007f519450d9d0 R11: 0000000000000202 R12: 0000000000000046 [ 599.709340] R13: ffffc9000665bf78 R14: 0000000000000000 R15: 00007f5195574040 [ 599.709340] ? trace_hardirqs_off_caller+0x43/0xb1 [ 599.709340] Code: 29 f0 49 39 d8 4c 0f 47 c3 49 03 81 58 01 00 00 44 89 c1 4c 01 c2 4c 29 c3 48 c1 f8 03 49 0f af c4 48 c1 e0 0c 4c 01 e8 48 01 c6 <f3> a4 31 f6 4$ [ 599.709340] RIP: read_extent_buffer+0xdb/0xf4 [btrfs] RSP: ffffc9000665ba00 [ 599.762057] ---[ end trace fe00d7af61b9f49e ]---
This is because the 'offset' field starts at an offset of 37 bytes (offsetof(struct btrfs_file_extent_item, offset)), has a length of 8 bytes and therefore attemping to read it causes a 1 byte access beyond the end of the leaf, as the first item's content in a leaf is located at the tail of the leaf, the item size is 44 bytes and the offset of that field plus its length (37 + 8 = 45) goes beyond the item's size by 1 byte.
So fix this by accessing the 'offset' and 'disk_bytenr' fields after jumping to the 'out' label if we are processing an inline extent. We move the reading operation of the 'disk_bytenr' field too because we have the same problem as for the 'offset' field explained above when the inline data is less then 8 bytes. The access to the 'generation' field is also moved but just for the sake of grouping access to all the fields.
--- fs/btrfs/send.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/btrfs/send.c +4 -3
@@ -5165,15 +5165,12 @@ static int is_extent_unchanged(struct send_ctx *sctx, goto out; } - right_disknr =btrfs_file_extent_disk_bytenr (eb, ei);if (right_type ==BTRFS_FILE_EXTENT_INLINE ) { right_len =btrfs_file_extent_inline_len (eb, slot, ei); right_len =PAGE_ALIGN (right_len); }else { right_len =btrfs_file_extent_num_bytes (eb, ei); } - right_offset =btrfs_file_extent_offset (eb, ei); - right_gen =btrfs_file_extent_generation (eb, ei);/* * Are we at extent 8? If yes, we know the extent is changed.
@@ -5198,6 +5195,10 @@ static int is_extent_unchanged(struct send_ctx *sctx, goto out; } + right_disknr =btrfs_file_extent_disk_bytenr (eb, ei); + right_offset =btrfs_file_extent_offset (eb, ei); + right_gen =btrfs_file_extent_generation (eb, ei); + left_offset_fixed = left_offset;if (key.offset < ekey->offset) {/* Fix the right offset for 2a and 7. */
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 75/98 drm/msm: Fix possible null dereference on failure of get_pages()
In reply to Sasha LevinFrom: Ben Hutchings <[email protected]>
[ Upstream commit 3976626ea3d2011f8fd3f3a47070a8b792018253 ]
Commit 62e3a3e342af changed get_pages() to initialise msm_gem_object::pages before trying to initialise msm_gem_object::sgt, so that put_pages() would properly clean up pages in the failure case.
However, this means that put_pages() now needs to check that msm_gem_object::sgt is not null before trying to clean it up, and this check was only applied to part of the cleanup code. Move it all into the conditional block. (Strictly speaking we don't need to make the kfree() conditional, but since we can't avoid checking for null ourselves we may as well do so.)
--- drivers/gpu/drm/msm/msm_gem.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
drivers/gpu/drm/msm/msm_gem.c +11 -9
@@ -118,17 +118,19 @@ static void put_pages(struct drm_gem_object *obj)struct msm_gem_object *msm_obj =to_msm_bo (obj);if (msm_obj->pages) { -/* For non-cached buffers, ensure the new pages are clean -* because display controller, GPU, etc. are not coherent: -*/ -if (msm_obj->flags & (MSM_BO_WC |MSM_BO_UNCACHED )) -dma_unmap_sg (obj->dev->dev, msm_obj->sgt->sgl, - msm_obj->sgt->nents,DMA_BIDIRECTIONAL ); +if (msm_obj->sgt) { +/* For non-cached buffers, ensure the new +* pages are clean because display controller, +* GPU, etc. are not coherent: +*/ +if (msm_obj->flags & (MSM_BO_WC |MSM_BO_UNCACHED )) +dma_unmap_sg (obj->dev->dev, msm_obj->sgt->sgl, + msm_obj->sgt->nents, +DMA_BIDIRECTIONAL ); -if (msm_obj->sgt)sg_free_table (msm_obj->sgt); - -kfree (msm_obj->sgt); +kfree (msm_obj->sgt); + }if (use_pages (obj))drm_gem_put_pages (obj, msm_obj->pages, true, false);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 76/98 ARM: tegra: Fix ULPI regression on Tegra20
In reply to Sasha LevinFrom: Marcel Ziswiler <[email protected]>
[ Upstream commit 4c9a27a6c66d4427f3cba4019d4ba738fe99fa87 ]
Since commit f8f8f1d04494 ("clk: Don't touch hardware when reparenting during registration") ULPI has been broken on Tegra20 leading to the following error message during boot:
[ 1.974698] ulpi_phy_power_on: ulpi write failed [ 1.979384] tegra-ehci c5004000.usb: Failed to power on the phy [ 1.985434] tegra-ehci: probe of c5004000.usb failed with error -110
Debugging through the changes and finally also consulting the TRM revealed that rather than the CDEV2 clock off OSC requiring such pin muxing actually the PLL_P_OUT4 clock is in use. It looks like so far it just worked by chance of that one having been enabled which Stephen's commit now changed when reparenting sclk away from pll_p_out4 leaving that one disabled. Fix this by properly assigning the PLL_P_OUT4 clock as the ULPI PHY clock.
--- arch/arm/boot/dts/tegra20.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/tegra20.dtsi +1 -1
@@ -690,7 +690,7 @@ phy_type = "ulpi"; clocks = <&tegra_car TEGRA20_CLK_USB2>, <&tegra_car TEGRA20_CLK_PLL_U>, - <&tegra_car TEGRA20_CLK_CDEV2>; + <&tegra_car TEGRA20_CLK_PLL_P_OUT4>; clock-names = "reg", "pll_u", "ulpi-link"; resets = <&tegra_car 58>, <&tegra_car 22>; reset-names = "usb", "utmi-pads";
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 77/98 module: fix DEBUG_SET_MODULE_RONX typo
In reply to Sasha LevinFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 4d217a5adccf5e806790c37c61cc374a08bd7381 ]
The newly added 'rodata_enabled' global variable is protected by the wrong #ifdef, leading to a link error when CONFIG_DEBUG_SET_MODULE_RONX is turned on:
kernel/module.o: In function `disable_ro_nx':
module.c:(.text.unlikely.disable_ro_nx+0x88): undefined reference to rodata_enabled' kernel/module.o: In function module_disable_ro':
module.c:(.text.module_disable_ro+0x8c): undefined reference to rodata_enabled' kernel/module.o: In function module_enable_ro':
module.c:(.text.module_enable_ro+0xb0): undefined reference to `rodata_enabled'
CONFIG_SET_MODULE_RONX does not exist, so use the correct one instead.
--- init/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
init/main.c +1 -1
@@ -915,7 +915,7 @@ static int try_to_run_init_process(const char *init_filename) static noinline void __init kernel_init_freeable(void); -#if defined(CONFIG_DEBUG_RODATA ) || defined(CONFIG_SET_MODULE_RONX ) +#if defined(CONFIG_DEBUG_RODATA ) || defined(CONFIG_DEBUG_SET_MODULE_RONX )bool rodata_enabled__ro_after_init = true;static int __init set_debug_rodata (char *str) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 78/98 iio: pressure: zpa2326: Remove always-true check which confuses gcc
In reply to Sasha LevinFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit f61dfff2f5b9fcb087bf5c444bc44b444709588f ]
With gcc 4.1.2:
drivers/iio/pressure/zpa2326.c: In function ‘zpa2326_wait_oneshot_completion’:
drivers/iio/pressure/zpa2326.c:868: warning: ‘ret’ may be used uninitialized in this function
When testing for "timeout < 0", timeout is already guaranteed to be strict negative, so the branch is always taken, and ret is thus always initialized. But (some version of) gcc is not smart enough to notice.
Remove the check to fix this.
As there is no other code in between assigning the error codes and returning them, the error codes can be returned immediately, and the intermediate variable can be dropped.
Drop the "else" to please checkpatch.
--- drivers/iio/pressure/zpa2326.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
drivers/iio/pressure/zpa2326.c +3 -7
@@ -869,7 +869,6 @@ static irqreturn_t zpa2326_handle_threaded_irq(int irq, void *data)static int zpa2326_wait_oneshot_completion (const struct iio_dev *indio_dev,struct zpa2326_private *private) { -int ret;unsigned int val;long timeout;
@@ -891,14 +890,11 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev,/* Timed out. */ zpa2326_warn (indio_dev,"no one shot interrupt occurred (%ld)" , timeout); - ret = -ETIME ; - }else if (timeout <0 ) { -zpa2326_warn (indio_dev, -"wait for one shot interrupt cancelled" ); - ret = -ERESTARTSYS ; +return -ETIME ; } -return ret; +zpa2326_warn (indio_dev,"wait for one shot interrupt cancelled" ); +return -ERESTARTSYS ; } static int zpa2326_init_managed_irq(struct device *parent,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 79/98 l2tp: remove configurable payload offset
In reply to Sasha LevinFrom: James Chapman <[email protected]>
[ Upstream commit 900631ee6a2651dc4fbaecb8ef9fa5f1e3378853 ]
If L2TP_ATTR_OFFSET is set to a non-zero value in L2TPv3 tunnels, it results in L2TPv3 packets being transmitted which might not be compliant with the L2TPv3 RFC. This patch has l2tp ignore the offset setting and send all packets with no offset.
In more detail:
L2TPv2 supports a variable offset from the L2TPv2 header to the payload. The offset value is indicated by an optional field in the L2TP header. Our L2TP implementation already detects the presence of the optional offset and skips that many bytes when handling data received packets. All transmitted packets are always transmitted with no offset.
L2TPv3 has no optional offset field in the L2TPv3 packet header. Instead, L2TPv3 defines optional fields in a "Layer-2 Specific Sublayer". At the time when the original L2TP code was written, there was talk at IETF of offset being implemented in a new Layer-2 Specific Sublayer. A L2TP_ATTR_OFFSET netlink attribute was added so that this offset could be configured and the intention was to allow it to be also used to set the tx offset for L2TPv2. However, no L2TPv3 offset was ever specified and the L2TP_ATTR_OFFSET parameter was forgotten about.
Setting L2TP_ATTR_OFFSET results in L2TPv3 packets being transmitted with the specified number of bytes padding between L2TPv3 header and payload. This is not compliant with L2TPv3 RFC3931. This change removes the configurable offset altogether while retaining L2TP_ATTR_OFFSET for backwards compatibility. Any L2TP_ATTR_OFFSET value is ignored.
--- net/l2tp/l2tp_core.c | 14 ++++---------- net/l2tp/l2tp_core.h | 3 --- net/l2tp/l2tp_debugfs.c | 4 ++-- net/l2tp/l2tp_netlink.c | 3 --- 4 files changed, 6 insertions(+), 18 deletions(-)
net/l2tp/l2tp_core.c +4 -10
@@ -845,10 +845,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, } } -/* Session data offset is handled differently for L2TPv2 and -* L2TPv3. For L2TPv2, there is an optional 16-bit value in -* the header. For L2TPv3, the offset is negotiated using AVPs -* in the session setup control protocol. +/* Session data offset is defined only for L2TPv2 and is +* indicated by an optional 16-bit value in the header. */ if (tunnel->version ==L2TP_HDR_VER_2 ) {/* If offset bit set, skip it. */
@@ -856,8 +854,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, offset =ntohs (*(__be16 *)ptr); ptr +=2 + offset; } - }else - ptr += session->offset; + } offset = ptr - optr;if (!pskb_may_pull (skb, offset))
@@ -1141,8 +1138,6 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf) } bufp += session->l2specific_len; } -if (session->offset) - bufp += session->offset;return bufp - optr; }
@@ -1827,7 +1822,7 @@ void l2tp_session_set_header_len(struct l2tp_session *session, int version)if (session->send_seq) session->hdr_len +=4 ; }else { - session->hdr_len =4 + session->cookie_len + session->l2specific_len + session->offset; + session->hdr_len =4 + session->cookie_len + session->l2specific_len;if (session->tunnel->encap ==L2TP_ENCAPTYPE_UDP ) session->hdr_len +=4 ; }
@@ -1878,7 +1873,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn session->recv_seq = cfg->recv_seq; session->lns_mode = cfg->lns_mode; session->reorder_timeout = cfg->reorder_timeout; - session->offset = cfg->offset; session->l2specific_type = cfg->l2specific_type; session->l2specific_len = cfg->l2specific_len; session->cookie_len = cfg->cookie_len;
net/l2tp/l2tp_core.h +0 -3
@@ -68,7 +68,6 @@ struct l2tp_session_cfg {int debug;/* bitmask of debug message * categories */ u16 vlan_id;/* VLAN pseudowire only */ -u16 offset;/* offset to payload */ u16 l2specific_len;/* Layer 2 specific length */ u16 l2specific_type;/* Layer 2 specific type */ u8 cookie[8 ];/* optional cookie */
@@ -94,8 +93,6 @@ struct l2tp_session {int cookie_len;u8 peer_cookie[8 ];int peer_cookie_len; -u16 offset;/* offset from end of L2TP header -to beginning of data */ u16 l2specific_len;u16 l2specific_type;u16 hdr_len;
net/l2tp/l2tp_debugfs.c +2 -2
@@ -181,8 +181,8 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v) session->lns_mode ?"LNS" :"LAC" , session->debug, jiffies_to_msecs(session->reorder_timeout)); -seq_printf (m," offset %hu l2specific %hu/%hu\n" , - session->offset, session->l2specific_type, session->l2specific_len); +seq_printf (m," offset 0 l2specific %hu/%hu\n" , + session->l2specific_type, session->l2specific_len);if (session->cookie_len) { seq_printf(m, " cookie %02x%02x%02x%02x", session->cookie[0], session->cookie[1],
net/l2tp/l2tp_netlink.c +0 -3
@@ -536,9 +536,6 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf }if (tunnel->version >2 ) { -if (info->attrs[L2TP_ATTR_OFFSET ]) - cfg.offset =nla_get_u16 (info->attrs[L2TP_ATTR_OFFSET ]); -if (info->attrs[L2TP_ATTR_DATA_SEQ ]) cfg.data_seq =nla_get_u8 (info->attrs[L2TP_ATTR_DATA_SEQ ]);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 80/98 macsec: fix memory leaks when skb_to_sgvec fails
In reply to Sasha LevinFrom: Sabrina Dubroca <[email protected]>
[ Upstream commit 5aba2ba5030b66a6f8c93049b718556f9aacd7c6 ]
--- drivers/net/macsec.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/macsec.c +2 -0
@@ -744,6 +744,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,sg_init_table (sg, ret); ret =skb_to_sgvec (skb, sg,0 , skb->len);if (unlikely (ret <0 )) { +aead_request_free (req);macsec_txsa_put (tx_sa);kfree_skb (skb);return ERR_PTR (ret);
@@ -956,6 +957,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,sg_init_table (sg, ret); ret =skb_to_sgvec (skb, sg,0 , skb->len);if (unlikely (ret <0 )) { +aead_request_free (req);kfree_skb (skb);return ERR_PTR (ret); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 81/98 perf/core: Fix locking for children siblings group read
In reply to Sasha LevinFrom: Jiri Olsa <[email protected]>
[ Upstream commit 2aeb1883547626d82c597cce2c99f0b9c62e2425 ]
We're missing ctx lock when iterating children siblings within the perf_read path for group reading. Following race and crash can happen:
User space doing read syscall on event group leader:
T1:
perf_read
lock event->ctx->mutex
perf_read_group
lock leader->child_mutex
__perf_read_group_add(child)
list_for_each_entry(sub, &leader->sibling_list, group_entry)----> sub might be invalid at this point, because it could
get removed via perf_event_exit_task_context in T2
Child exiting and cleaning up its events:
T2:
perf_event_exit_task_context
lock ctx->mutex
list_for_each_entry_safe(child_event, next, &child_ctx->event_list,...
perf_event_exit_event(child)
lock ctx->lock
perf_group_detach(child)
unlock ctx->lock----> child is removed from sibling_list without any sync
with T1 path above
...
free_event(child)
Before the child is removed from the leader's child_list, (and thus is omitted from perf_read_group processing), we need to ensure that perf_read_group touches child's siblings under its ctx->lock.
Peter further notes:
| One additional note; this bug got exposed by commit:
|
| ba5213ae6b88 ("perf/core: Correct event creation with PERF_FORMAT_GROUP")
|
| which made it possible to actually trigger this code-path.--- kernel/events/core.c | 5 +++++ 1 file changed, 5 insertions(+)
kernel/events/core.c +5 -0
@@ -4331,7 +4331,9 @@ EXPORT_SYMBOL_GPL(perf_event_read_value);static int __perf_read_group_add (struct perf_event *leader,u64 read_format,u64 *values) { +struct perf_event_context *ctx = leader->ctx;struct perf_event *sub; +unsigned long flags;int n =1 ;/* skip @nr */ int ret;
@@ -4361,12 +4363,15 @@ static int __perf_read_group_add(struct perf_event *leader,if (read_format &PERF_FORMAT_ID ) values[n++] =primary_event_id (leader); +raw_spin_lock_irqsave (&ctx->lock, flags); +list_for_each_entry (sub, &leader->sibling_list, group_entry) { values[n++] +=perf_event_count (sub);if (read_format &PERF_FORMAT_ID ) values[n++] =primary_event_id (sub); } +raw_spin_unlock_irqrestore (&ctx->lock, flags);return 0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 82/98 cifs: Use ULL suffix for 64-bit constant
In reply to Sasha LevinFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit 3995bbf53bd2047f2720c6fdd4bf38f6d942a0c0 ]
On 32-bit (e.g. with m68k-linux-gnu-gcc-4.1):
fs/cifs/inode.c: In function ‘simple_hashstr’:
fs/cifs/inode.c:713: warning: integer constant is too large for ‘long’ type
--- fs/cifs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/cifs/inode.c +1 -1
@@ -704,7 +704,7 @@ cifs_get_file_info(struct file *filp)/* Simple function to return a 64 bit hash of string. Rarely called */ static __u64 simple_hashstr (const char *str) { -const __u64 hash_mult =1125899906842597L ;/* a big enough prime */ +const __u64 hash_mult =1125899906842597ULL ;/* a big enough prime */ __u64 hash =0 ;while (*str)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 83/98 futex: futex_wake_op, do not fail on invalid op
In reply to Sasha LevinFrom: Jiri Slaby <[email protected]>
[ Upstream commit e78c38f6bdd900b2ad9ac9df8eff58b745dc5b3c ]
In commit 30d6e0a4190d ("futex: Remove duplicated code and fix undefined behaviour"), I let FUTEX_WAKE_OP to fail on invalid op. Namely when op should be considered as shift and the shift is out of range (< 0 or > 31).
But strace's test suite does this madness:
futex(0x7fabd78bcffc, 0x5, 0xfacefeed, 0xb, 0x7fabd78bcffc, 0xa0caffee); futex(0x7fabd78bcffc, 0x5, 0xfacefeed, 0xb, 0x7fabd78bcffc, 0xbadfaced); futex(0x7fabd78bcffc, 0x5, 0xfacefeed, 0xb, 0x7fabd78bcffc, 0xffffffff);
When I pick the first 0xa0caffee, it decodes as:
0x80000000 & 0xa0caffee: oparg is shift
0x70000000 & 0xa0caffee: op is FUTEX_OP_OR 0x0f000000 & 0xa0caffee: cmp is FUTEX_OP_CMP_EQ 0x00fff000 & 0xa0caffee: oparg is sign-extended 0xcaf = -849 0x00000fff & 0xa0caffee: cmparg is sign-extended 0xfee = -18
That means the op tries to do this:
(futex |= (1 << (-849))) == -18
which is completely bogus. The new check of op in the code is:
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) {
if (oparg < 0 || oparg > 31)
return -EINVAL;
oparg = 1 << oparg;
}which results obviously in the "Invalid argument" errno:
FAIL: futex
===========
futex(0x7fabd78bcffc, 0x5, 0xfacefeed, 0xb, 0x7fabd78bcffc, 0xa0caffee) = -1: Invalid argument futex.test: failed test: ../futex failed with code 1
So let us soften the failure to print only a (ratelimited) message, crop the value and continue as if it were right. When userspace keeps up, we can switch this to return -EINVAL again.
[v2] Do not return 0 immediatelly, proceed with the cropped value.
--- kernel/futex.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
kernel/futex.c +10 -2
@@ -1467,8 +1467,16 @@ static int futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr)int oldval, ret;if (encoded_op & (FUTEX_OP_OPARG_SHIFT <<28 )) { -if (oparg <0 || oparg >31 ) -return -EINVAL ; +if (oparg <0 || oparg >31 ) { +char comm[sizeof (current->comm)]; +/* +* kill this print and return -EINVAL when userspace +* is sane again +*/ +pr_info_ratelimited ("futex_wake_op: %s tries to shift op by %d; fix this program\n" , +get_task_comm (comm, current), oparg); + oparg &=31 ; + } oparg =1 << oparg; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 84/98 ALSA: hda - Fix incorrect usage of IS_REACHABLE()
In reply to Sasha LevinFrom: Takashi Iwai <[email protected]>
[ Upstream commit 6a30abaa40b62aed46ef12ea4c16c48565bdb376 ]
The commit c469652bb5e8 ("ALSA: hda - Use IS_REACHABLE() for dependency on input") simplified the dependencies with IS_REACHABLE() macro, but it broke due to its incorrect usage: it should have been IS_REACHABLE(CONFIG_INPUT) instead of IS_REACHABLE(INPUT).
--- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/hda/patch_realtek.c +1 -1
@@ -3499,7 +3499,7 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, } } -#if IS_REACHABLE (INPUT ) +#if IS_REACHABLE (CONFIG_INPUT )static void gpio2_mic_hotkey_event (struct hda_codec *codec,struct hda_jack_callback *event) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 85/98 test_bpf: Fix testing with CONFIG_BPF_JIT_ALWAYS_ON=y on other arches
In reply to Sasha LevinFrom: Thadeu Lima de Souza Cascardo <[email protected]>
[ Upstream commit 52fda36d63bfc8c8e8ae5eda8eb5ac6f52cd67ed ]
Function bpf_fill_maxinsns11 is designed to not be able to be JITed on x86_64. So, it fails when CONFIG_BPF_JIT_ALWAYS_ON=y, and commit 09584b406742 ("bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y") makes sure that failure is detected on that case.
However, it does not fail on other architectures, which have a different JIT compiler design. So, test_bpf has started to fail to load on those.
After this fix, test_bpf loads fine on both x86_64 and ppc64el.
--- lib/test_bpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/test_bpf.c +1 -1
@@ -4874,7 +4874,7 @@ static struct bpf_test tests[] = { { "BPF_MAXINSNS: Jump, gap, jump, ...", { }, -#ifdef CONFIG_BPF_JIT_ALWAYS_ON +#if defined(CONFIG_BPF_JIT_ALWAYS_ON ) && defined(CONFIG_X86 )CLASSIC |FLAG_NO_DATA |FLAG_EXPECTED_FAIL , #else CLASSIC | FLAG_NO_DATA,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 86/98 xen-netfront: Update features after registering netdev
In reply to Sasha LevinFrom: Ross Lagerwall <[email protected]>
[ Upstream commit 45c8184c1bed1ca8a7f02918552063a00b909bf5 ]
Update the features after calling register_netdev() otherwise the device features are not set up correctly and it not possible to change the MTU of the device. After this change, the features reported by ethtool match the device's features before the commit which introduced the issue and it is possible to change the device's MTU.
--- drivers/net/xen-netfront.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/xen-netfront.c +4 -4
@@ -1994,10 +1994,6 @@ static int xennet_connect(struct net_device *dev)/* talk_to_netback() sets the correct number of queues */ num_queues = dev->real_num_tx_queues; -rtnl_lock (); -netdev_update_features (dev); -rtnl_unlock (); -if (dev->reg_state ==NETREG_UNINITIALIZED ) { err =register_netdev (dev);if (err) {
@@ -2007,6 +2003,10 @@ static int xennet_connect(struct net_device *dev) } } +rtnl_lock (); +netdev_update_features (dev); +rtnl_unlock (); +/* * All public and private state should now be sane. Get * ready to start sending and receiving packets and give the driver
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 87/98 sparc64: Fix regression in pmdp_invalidate().
In reply to Sasha LevinFrom: "David S. Miller" <[email protected]>
[ Upstream commit cfb61b5e3e09f8b49bc4d685429df75f45127adc ]
pmdp_invalidate() was changed to update the pmd atomically (to not lose dirty/access bits) and return the original pmd value.
However, in doing so, we lost a lot of the essential work that set_pmd_at() does, namely to update hugepage mapping counts and queuing up the batched TLB flush entry.
Thus we were not flushing entries out of the TLB when making such PMD changes.
Fix this by abstracting the accounting work of set_pmd_at() out into a separate function, and call it from pmdp_establish().
--- arch/sparc/mm/tlb.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
arch/sparc/mm/tlb.c +13 -6
@@ -163,13 +163,10 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,pte_unmap (pte); } -void set_pmd_at (struct mm_struct *mm,unsigned long addr, -pmd_t *pmdp,pmd_t pmd) -{ -pmd_t orig = *pmdp; - - *pmdp = pmd; +static void __set_pmd_acct (struct mm_struct *mm,unsigned long addr, +pmd_t orig,pmd_t pmd) +{if (mm == &init_mm)return ;
@@ -219,6 +216,15 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, } } +void set_pmd_at (struct mm_struct *mm,unsigned long addr, +pmd_t *pmdp,pmd_t pmd) +{ +pmd_t orig = *pmdp; + + *pmdp = pmd; +__set_pmd_acct (mm, addr, orig, pmd); +} +static inline pmd_t pmdp_establish (struct vm_area_struct *vma,unsigned long address,pmd_t *pmdp,pmd_t pmd) {
@@ -227,6 +233,7 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,do { old = *pmdp; }while (cmpxchg64 (&pmdp->pmd, old.pmd, pmd.pmd) != old.pmd); +__set_pmd_acct (vma->vm_mm, address, old, pmd);return old; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 88/98 xen-netfront: Fix mismatched rtnl_unlock
In reply to Sasha LevinFrom: Ross Lagerwall <[email protected]>
[ Upstream commit cb257783c2927b73614b20f915a91ff78aa6f3e8 ]
--- drivers/net/xen-netfront.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/xen-netfront.c +2 -1
@@ -1848,7 +1848,7 @@ static int talk_to_netback(struct xenbus_device *dev, err =xen_net_read_mac (dev, info->netdev->dev_addr);if (err) {xenbus_dev_fatal (dev, err,"parsing %s/mac" , dev->nodename); - goto out; + goto out_unlocked; }rtnl_lock ();
@@ -1963,6 +1963,7 @@ static int talk_to_netback(struct xenbus_device *dev,xennet_destroy_queues (info); out:rtnl_unlock (); +out_unlocked:device_unregister (&dev->dev);return err; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 89/98 enic: do not overwrite error code
In reply to Sasha LevinFrom: Govindarajulu Varadarajan <[email protected]>
[ Upstream commit 56f772279a762984f6e9ebbf24a7c829faba5712 ]
In failure path, we overwrite err to what vnic_rq_disable() returns. In case it returns 0, enic_open() returns success in case of error.
--- drivers/net/ethernet/cisco/enic/enic_main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/net/ethernet/cisco/enic/enic_main.c +4 -5
@@ -1708,7 +1708,7 @@ static int enic_open(struct net_device *netdev) {struct enic *enic =netdev_priv (netdev);unsigned int i; -int err; +int err, ret; err =enic_request_intr (enic);if (err) {
@@ -1766,10 +1766,9 @@ static int enic_open(struct net_device *netdev) err_out_free_rq:for (i =0 ; i < enic->rq_count; i++) { - err =vnic_rq_disable (&enic->rq[i]); -if (err) -return err; -vnic_rq_clean (&enic->rq[i], enic_free_rq_buf); + ret =vnic_rq_disable (&enic->rq[i]); +if (!ret) +vnic_rq_clean (&enic->rq[i], enic_free_rq_buf); }enic_dev_notify_unset (enic); err_out_free_intr:
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 90/98 bonding: ratelimit failed speed/duplex update warning
In reply to Sasha LevinFrom: Andreas Born <[email protected]>
[ Upstream commit 11e9d7829dd08dbafb24517fe922f11c3a8a9dc2 ]
bond_miimon_commit() handles the UP transition for each slave of a bond in the case of MII. It is triggered 10 times per second for the default MII Polling interval of 100ms. For device drivers that do not implement __ethtool_get_link_ksettings() the call to bond_update_speed_duplex() fails persistently while the MII status could remain UP. That is, in this and other cases where the speed/duplex update keeps failing over a longer period of time while the MII state is UP, a warning is printed every MII polling interval.
To address these excessive warnings net_ratelimit() should be used. Printing a warning once would not be sufficient since the call to bond_update_speed_duplex() could recover to succeed and fail again later. In that case there would be no new indication what went wrong.
--- drivers/net/bonding/bond_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/bonding/bond_main.c +4 -3
@@ -2132,9 +2132,10 @@ static void bond_miimon_commit(struct bonding *bond)if (bond_update_speed_duplex (slave) &&bond_needs_speed_duplex (bond)) { slave->link =BOND_LINK_DOWN ; -netdev_warn (bond->dev, -"failed to get link speed/duplex for %s\n" , - slave->dev->name); +if (net_ratelimit ()) +netdev_warn (bond->dev, +"failed to get link speed/duplex for %s\n" , + slave->dev->name);continue ; } bond_set_slave_link_state(slave, BOND_LINK_UP,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 91/98 tty: serial: pl011: add ttyAMA for matching pl011 console
In reply to Sasha LevinFrom: Sudeep Holla <[email protected]>
[ Upstream commit aea9a80ba98a0c9b4de88850260e9fbdcc98360b ]
Commit c7cef0a84912 ("console: Add extensible console matching") added match() method to struct console which allows the console to perform console command line matching instead of (or in addition to) default console matching (ie., by fixed name and index).
Commit ad1696f6f09d ("ACPI: parse SPCR and enable matching console") introduced support for SPCR as matching console.
Commit 10879ae5f12e ("serial: pl011: add console matching function") added the match method for pl011 console which checks for the console string to be "pl011"
Now on a platform which has both SPCR in the ACPI tables and ttyAMA in the command line, the ttyAMA is chosen as "selected console" but it doesn't pass the matching console method which results in CON_CONSDEV not being set on the "selected console".
As a result of that, the bootconsole(SPCR in the above case) is not unregistered and all the beginning boot messages are seen twice.
This patch adds "ttyAMA" so that it's considered to match pl011 console.
--- drivers/tty/serial/amba-pl011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/amba-pl011.c +1 -1
@@ -2361,7 +2361,7 @@ static int __init pl011_console_match(struct console *co, char *name, int idx,resource_size_t addr;int i; -if (strcmp (name,"pl011" ) !=0 ) +if (strcmp (name,"pl011" ) !=0 ||strcmp (name,"ttyAMA" ) !=0 )return -ENODEV ;if (uart_parse_earlycon (options, &iotype, &addr, &options))
Signature · 1 line
2.17.1
Re: [PATCH AUTOSEL 4.9 91/98] tty: serial: pl011: add ttyAMA for matching pl011 console
Hi Sasha,
Quoted 4 lines · Sasha Levin
From: Sudeep Holla <[email protected]>
[ Upstream commit
aea9a80ba98a0c9b4de88850260e9fbdcc98360b]
This commit was later reverted with commit b767ad726c2a ("Revert "tty: serial:
pl011: add ttyAMA for matching pl011 console"") as it caused regression else where. So I assume you can drop this. Unfortunately the revert doesn't carry fixes tag hence I thought of mentioning to you.
The original issue still exists.
--
Regards,
Sudeep
Sasha Levin
maintainerRe: [PATCH AUTOSEL 4.9 91/98] tty: serial: pl011: add ttyAMA for matching pl011 console
Quoted 8 lines · Sudeep Holla
Hi Sasha,
Quoted 4 lines · Sasha Levin
From: Sudeep Holla <[email protected]>
[ Upstream commit
aea9a80ba98a0c9b4de88850260e9fbdcc98360b]
Quoted 6 lines
This commit was later reverted with commit
b767ad726c2a("Revert "tty: serial:
pl011: add ttyAMA for matching pl011 console"") as it caused regression else where. So I assume you can drop this. Unfortunately the revert doesn't carry fixes tag hence I thought of mentioning to you.The original issue still exists.
I'll drop it. Thanks for the heads-up!
--
Thanks,
Sasha
Sasha Levin
maintainerPATCH 92/98 nvmet: fix space padding in serial number
In reply to Sasha LevinFrom: Daniel Verkamp <[email protected]>
[ Upstream commit c73996984902516745bc587d5e8a0b2e034aea05 ]
Commit 42de82a8b544 previously attempted to fix this, and it did correctly pad the MN and FR fields with spaces, but the SN field still contains 0 bytes. The current code fills out the first 16 bytes with hex2bin, leaving the last 4 bytes zeroed. Rather than adding a lot of error-prone math to avoid overwriting SN twice, just set the whole thing to spaces up front (it's only 20 bytes).
--- drivers/nvme/target/admin-cmd.c | 1 + 1 file changed, 1 insertion(+)
drivers/nvme/target/admin-cmd.c +1 -0
@@ -192,6 +192,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) id->vid =0 ; id->ssvid =0 ; +memset (id->sn,' ' ,sizeof (id->sn));bin2hex (id->sn, &ctrl->subsys->serial,min (sizeof (ctrl->subsys->serial),sizeof (id->sn) /2 ));copy_and_pad (id->mn,sizeof (id->mn), model,sizeof (model) -1 );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 93/98 iio: buffer: fix the function signature to match implementation
In reply to Sasha LevinFrom: Phil Reid <[email protected]>
[ Upstream commit 92397a6c38d139d50fabbe9e2dc09b61d53b2377 ]
linux/iio/buffer-dma.h was not updated to when length was changed to unsigned int.
--- include/linux/iio/buffer-dma.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/iio/buffer-dma.h +1 -1
@@ -141,7 +141,7 @@ int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, char __user *user_buffer);size_t iio_dma_buffer_data_available (struct iio_buffer *buffer);int iio_dma_buffer_set_bytes_per_datum (struct iio_buffer *buffer,size_t bpd); -int iio_dma_buffer_set_length (struct iio_buffer *buffer,int length); +int iio_dma_buffer_set_length (struct iio_buffer *buffer,unsigned int length);int iio_dma_buffer_request_update (struct iio_buffer *buffer); int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 94/98 x86/paravirt: Fix some warning messages
In reply to Sasha LevinFrom: Dan Carpenter <[email protected]>
[ Upstream commit 571d0563c8881595f4ab027aef9ed1c55e3e7b7c ]
The first argument to WARN_ONCE() is a condition.
--- arch/x86/kernel/paravirt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/paravirt.c +2 -2
@@ -90,7 +90,7 @@ unsigned paravirt_patch_call(void *insnbuf,if (len <5 ) {#ifdef CONFIG_RETPOLINE -WARN_ONCE ("Failing to patch indirect CALL in %ps\n" , (void *)addr); +WARN_ONCE (1 ,"Failing to patch indirect CALL in %ps\n" , (void *)addr);#endif return len;/* call too long for patch site */ }
@@ -110,7 +110,7 @@ unsigned paravirt_patch_jmp(void *insnbuf, const void *target,if (len <5 ) {#ifdef CONFIG_RETPOLINE -WARN_ONCE ("Failing to patch indirect JMP in %ps\n" , (void *)addr); +WARN_ONCE (1 ,"Failing to patch indirect JMP in %ps\n" , (void *)addr);#endif return len;/* call too long for patch site */ }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 95/98 IB/mlx4: Fix an error handling path in 'mlx4_ib_rereg_user_mr()'
In reply to Sasha LevinFrom: Christophe Jaillet <[email protected]>
[ Upstream commit 3dc7c7badb7502ec3e3aa817a8bdd9e53aa54c52 ]
Before returning -EPERM we should release some resources, as already done in the other error handling path of the function.
--- drivers/infiniband/hw/mlx4/mr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/infiniband/hw/mlx4/mr.c +5 -2
@@ -247,8 +247,11 @@ int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags, }if (flags &IB_MR_REREG_ACCESS ) { -if (ib_access_writable (mr_access_flags) && !mmr->umem->writable) -return -EPERM ; +if (ib_access_writable (mr_access_flags) && + !mmr->umem->writable) { + err = -EPERM ; + goto release_mpt_entry; + } err =mlx4_mr_hw_change_access (dev->dev, *pmpt_entry,convert_access (mr_access_flags));
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 96/98 libertas: call into generic suspend code before turning off power
In reply to Sasha LevinFrom: Daniel Mack <[email protected]>
[ Upstream commit 4f666675cdff0b986195413215eb062b7da6586f ]
When powering down a SDIO connected card during suspend, make sure to call into the generic lbs_suspend() function before pulling the plug. This will make sure the card is successfully deregistered from the system to avoid communication to the card starving out.
--- drivers/net/wireless/marvell/libertas/if_sdio.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/wireless/marvell/libertas/if_sdio.c +4 -0
@@ -1368,6 +1368,10 @@ static int if_sdio_suspend(struct device *dev)if (priv->wol_criteria ==EHS_REMOVE_WAKEUP ) {dev_info (dev,"Suspend without wake params -- powering down card\n" );if (priv->fw_ready) { + ret =lbs_suspend (priv); +if (ret) +return ret; + priv->power_up_on_resume = true;if_sdio_power_off (card); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 97/98 xhci: Fix USB3 NULL pointer dereference at logical disconnect.
In reply to Sasha LevinFrom: Mathias Nyman <[email protected]>
[ Upstream commit 2278446e2b7cd33ad894b32e7eb63afc7db6c86e ]
Hub driver will try to disable a USB3 device twice at logical disconnect, racing with xhci_free_dev() callback from the first port disable.
This can be triggered with "udisksctl power-off --block-device <disk>" or by writing "1" to the "remove" sysfs file for a USB3 device in 4.17-rc4.
USB3 devices don't have a similar disabled link state as USB2 devices, and use a U3 suspended link state instead. In this state the port is still enabled and connected.
hub_port_connect() first disconnects the device, then later it notices that device is still enabled (due to U3 states) it will try to disable the port again (set to U3).
The xhci_free_dev() called during device disable is async, so checking for existing xhci->devs[i] when setting link state to U3 the second time was successful, even if device was being freed.
The regression was caused by, and whole thing revealed by, Commit 44a182b9d177 ("xhci: Fix use-after-free in xhci_free_virt_device") which sets xhci->devs[i]->udev to NULL before xhci_virt_dev() returned. and causes a NULL pointer dereference the second time we try to set U3.
Fix this by checking xhci->devs[i]->udev exists before setting link state.
The original patch went to stable so this fix needs to be applied there as well.
--- drivers/usb/host/xhci-hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/xhci-hub.c +1 -1
@@ -366,7 +366,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, slot_id =0 ;for (i =0 ; i <MAX_HC_SLOTS ; i++) { -if (!xhci->devs[i]) +if (!xhci->devs[i] || !xhci->devs[i]->udev)continue ; speed = xhci->devs[i]->udev->speed; if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3))
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 98/98 perf tests: Fix indexing when invoking subtests
In reply to Sasha LevinFrom: Sandipan Das <[email protected]>
[ Upstream commit aa90f9f9554616d5738f7bedb4a8f0e5e14d1bc6 ]
Recently, the subtest numbering was changed to start from 1. While it is fine for displaying results, this should not be the case when the subtests are actually invoked.
Typically, the subtests are stored in zero-indexed arrays and invoked based on the index passed to the main test function. Since the index now starts from 1, the second subtest in the array (index 1) gets invoked instead of the first (index 0). This applies to all of the following subtests but for the last one, the subtest always fails because it does not meet the boundary condition of the subtest index being lesser than the number of subtests.
This can be observed on powerpc64 and x86_64 systems running Fedora 28 as shown below.
Before:
# perf test "builtin clang support" 55: builtin clang support : 55.1: builtin clang compile C source to IR : Ok 55.2: builtin clang compile C source to ELF object : FAILED!
# perf test "LLVM search and compile" 38: LLVM search and compile : 38.1: Basic BPF llvm compile : Ok 38.2: kbuild searching : Ok 38.3: Compile source for BPF prologue generation : Ok 38.4: Compile source for BPF relocation : FAILED!
# perf test "BPF filter" 40: BPF filter : 40.1: Basic BPF filtering : Ok 40.2: BPF pinning : Ok 40.3: BPF prologue generation : Ok 40.4: BPF relocation checker : FAILED!
After:
# perf test "builtin clang support" 55: builtin clang support : 55.1: builtin clang compile C source to IR : Ok 55.2: builtin clang compile C source to ELF object : Ok
# perf test "LLVM search and compile" 38: LLVM search and compile : 38.1: Basic BPF llvm compile : Ok 38.2: kbuild searching : Ok 38.3: Compile source for BPF prologue generation : Ok 38.4: Compile source for BPF relocation : Ok
# perf test "BPF filter" 40: BPF filter : 40.1: Basic BPF filtering : Ok 40.2: BPF pinning : Ok 40.3: BPF prologue generation : Ok 40.4: BPF relocation checker : Ok
--- tools/perf/tests/builtin-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/tests/builtin-test.c +2 -2
@@ -335,7 +335,7 @@ static int test_and_print(struct test *t, bool force_skip, int subtest)if (!t->subtest.get_nr)pr_debug ("%s:" , t->desc);else -pr_debug ("%s subtest %d:" , t->desc, subtest); +pr_debug ("%s subtest %d:" , t->desc, subtest +1 );switch (err) {case TEST_OK :
@@ -413,7 +413,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)for (subi =0 ; subi < subn; subi++) {pr_info ("%2d.%1d: %-*s:" , i, subi +1 , subw, t->subtest.get_desc (subi)); - err =test_and_print (t, skip, subi +1 ); + err =test_and_print (t, skip, subi);if (err !=TEST_OK && t->subtest.skip_if_fail) skip = true; }
Signature · 1 line
2.17.1