diff options
author | Mike Pagano <mpagano@gentoo.org> | 2017-07-16 10:25:21 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2017-07-16 10:25:21 -0400 |
commit | bafd606d04e2ca693c2a7ae18173b801d96ee7e6 (patch) | |
tree | e8551a878970f84b01d752d06b789e865a5b3520 | |
parent | Linux patch 4.4.76 (diff) | |
download | linux-patches-bafd606d04e2ca693c2a7ae18173b801d96ee7e6.tar.gz linux-patches-bafd606d04e2ca693c2a7ae18173b801d96ee7e6.tar.bz2 linux-patches-bafd606d04e2ca693c2a7ae18173b801d96ee7e6.zip |
Linux patch 4.4.774.4-80
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1076_linux-4.4.77.patch | 1575 |
2 files changed, 1579 insertions, 0 deletions
diff --git a/0000_README b/0000_README index a7fc0fec..2033f7cc 100644 --- a/0000_README +++ b/0000_README @@ -347,6 +347,10 @@ Patch: 1075_linux-4.4.76.patch From: http://www.kernel.org Desc: Linux 4.4.76 +Patch: 1076_linux-4.4.77.patch +From: http://www.kernel.org +Desc: Linux 4.4.77 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1076_linux-4.4.77.patch b/1076_linux-4.4.77.patch new file mode 100644 index 00000000..4a32231a --- /dev/null +++ b/1076_linux-4.4.77.patch @@ -0,0 +1,1575 @@ +diff --git a/Makefile b/Makefile +index 902ab134446e..bf49a61d02e2 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 76 ++SUBLEVEL = 77 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h +index 0b1ff4c1c14e..fffb2794dd89 100644 +--- a/arch/x86/include/asm/pat.h ++++ b/arch/x86/include/asm/pat.h +@@ -7,6 +7,7 @@ + bool pat_enabled(void); + void pat_disable(const char *reason); + extern void pat_init(void); ++extern void init_cache_modes(void); + + extern int reserve_memtype(u64 start, u64 end, + enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm); +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index d2bbe343fda7..e67b834279b2 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1048,6 +1048,13 @@ void __init setup_arch(char **cmdline_p) + if (mtrr_trim_uncached_memory(max_pfn)) + max_pfn = e820_end_of_ram_pfn(); + ++ /* ++ * This call is required when the CPU does not support PAT. If ++ * mtrr_bp_init() invoked it already via pat_init() the call has no ++ * effect. ++ */ ++ init_cache_modes(); ++ + #ifdef CONFIG_X86_32 + /* max_low_pfn get updated here */ + find_low_pfn_range(); +diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S +index 27f89c79a44b..423644c230e7 100644 +--- a/arch/x86/lib/copy_user_64.S ++++ b/arch/x86/lib/copy_user_64.S +@@ -80,7 +80,7 @@ ENTRY(copy_user_generic_unrolled) + movl %edx,%ecx + andl $63,%edx + shrl $6,%ecx +- jz 17f ++ jz .L_copy_short_string + 1: movq (%rsi),%r8 + 2: movq 1*8(%rsi),%r9 + 3: movq 2*8(%rsi),%r10 +@@ -101,7 +101,8 @@ ENTRY(copy_user_generic_unrolled) + leaq 64(%rdi),%rdi + decl %ecx + jnz 1b +-17: movl %edx,%ecx ++.L_copy_short_string: ++ movl %edx,%ecx + andl $7,%edx + shrl $3,%ecx + jz 20f +@@ -215,6 +216,8 @@ ENDPROC(copy_user_generic_string) + */ + ENTRY(copy_user_enhanced_fast_string) + ASM_STAC ++ cmpl $64,%edx ++ jb .L_copy_short_string /* less then 64 bytes, avoid the costly 'rep' */ + movl %edx,%ecx + 1: rep + movsb +diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c +index 6ad687d104ca..3f1bb4f93a5a 100644 +--- a/arch/x86/mm/pat.c ++++ b/arch/x86/mm/pat.c +@@ -36,14 +36,14 @@ + #undef pr_fmt + #define pr_fmt(fmt) "" fmt + +-static bool boot_cpu_done; +- +-static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT); +-static void init_cache_modes(void); ++static bool __read_mostly boot_cpu_done; ++static bool __read_mostly pat_disabled = !IS_ENABLED(CONFIG_X86_PAT); ++static bool __read_mostly pat_initialized; ++static bool __read_mostly init_cm_done; + + void pat_disable(const char *reason) + { +- if (!__pat_enabled) ++ if (pat_disabled) + return; + + if (boot_cpu_done) { +@@ -51,10 +51,8 @@ void pat_disable(const char *reason) + return; + } + +- __pat_enabled = 0; ++ pat_disabled = true; + pr_info("x86/PAT: %s\n", reason); +- +- init_cache_modes(); + } + + static int __init nopat(char *str) +@@ -66,7 +64,7 @@ early_param("nopat", nopat); + + bool pat_enabled(void) + { +- return !!__pat_enabled; ++ return pat_initialized; + } + EXPORT_SYMBOL_GPL(pat_enabled); + +@@ -204,6 +202,8 @@ static void __init_cache_modes(u64 pat) + update_cache_mode_entry(i, cache); + } + pr_info("x86/PAT: Configuration [0-7]: %s\n", pat_msg); ++ ++ init_cm_done = true; + } + + #define PAT(x, y) ((u64)PAT_ ## y << ((x)*8)) +@@ -224,6 +224,7 @@ static void pat_bsp_init(u64 pat) + } + + wrmsrl(MSR_IA32_CR_PAT, pat); ++ pat_initialized = true; + + __init_cache_modes(pat); + } +@@ -241,10 +242,9 @@ static void pat_ap_init(u64 pat) + wrmsrl(MSR_IA32_CR_PAT, pat); + } + +-static void init_cache_modes(void) ++void init_cache_modes(void) + { + u64 pat = 0; +- static int init_cm_done; + + if (init_cm_done) + return; +@@ -286,8 +286,6 @@ static void init_cache_modes(void) + } + + __init_cache_modes(pat); +- +- init_cm_done = 1; + } + + /** +@@ -305,10 +303,8 @@ void pat_init(void) + u64 pat; + struct cpuinfo_x86 *c = &boot_cpu_data; + +- if (!pat_enabled()) { +- init_cache_modes(); ++ if (pat_disabled) + return; +- } + + if ((c->x86_vendor == X86_VENDOR_INTEL) && + (((c->x86 == 0x6) && (c->x86_model <= 0xd)) || +diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c +index 0c2fae8d929d..73eb7fd4aec4 100644 +--- a/arch/x86/tools/relocs.c ++++ b/arch/x86/tools/relocs.c +@@ -992,11 +992,12 @@ static void emit_relocs(int as_text, int use_real_mode) + die("Segment relocations found but --realmode not specified\n"); + + /* Order the relocations for more efficient processing */ +- sort_relocs(&relocs16); + sort_relocs(&relocs32); + #if ELF_BITS == 64 + sort_relocs(&relocs32neg); + sort_relocs(&relocs64); ++#else ++ sort_relocs(&relocs16); + #endif + + /* Print the relocations */ +diff --git a/drivers/base/platform.c b/drivers/base/platform.c +index ba66330cea67..cb4ad6e98b28 100644 +--- a/drivers/base/platform.c ++++ b/drivers/base/platform.c +@@ -807,7 +807,7 @@ static ssize_t driver_override_store(struct device *dev, + const char *buf, size_t count) + { + struct platform_device *pdev = to_platform_device(dev); +- char *driver_override, *old = pdev->driver_override, *cp; ++ char *driver_override, *old, *cp; + + if (count > PATH_MAX) + return -EINVAL; +@@ -820,12 +820,15 @@ static ssize_t driver_override_store(struct device *dev, + if (cp) + *cp = '\0'; + ++ device_lock(dev); ++ old = pdev->driver_override; + if (strlen(driver_override)) { + pdev->driver_override = driver_override; + } else { + kfree(driver_override); + pdev->driver_override = NULL; + } ++ device_unlock(dev); + + kfree(old); + +@@ -836,8 +839,12 @@ static ssize_t driver_override_show(struct device *dev, + struct device_attribute *attr, char *buf) + { + struct platform_device *pdev = to_platform_device(dev); ++ ssize_t len; + +- return sprintf(buf, "%s\n", pdev->driver_override); ++ device_lock(dev); ++ len = sprintf(buf, "%s\n", pdev->driver_override); ++ device_unlock(dev); ++ return len; + } + static DEVICE_ATTR_RW(driver_override); + +diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c +index f300eba95bb1..1244cdf52859 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_object.c ++++ b/drivers/gpu/drm/virtio/virtgpu_object.c +@@ -81,8 +81,10 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, + return -ENOMEM; + size = roundup(size, PAGE_SIZE); + ret = drm_gem_object_init(vgdev->ddev, &bo->gem_base, size); +- if (ret != 0) ++ if (ret != 0) { ++ kfree(bo); + return ret; ++ } + bo->dumb = false; + virtio_gpu_init_ttm_placement(bo, pinned); + +diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c +index 1c02deab068f..9eca4b41fa0a 100644 +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -2287,6 +2287,10 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + ++ if (cmd.port_num < rdma_start_port(ib_dev) || ++ cmd.port_num > rdma_end_port(ib_dev)) ++ return -EINVAL; ++ + INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd, + out_len); + +@@ -2827,6 +2831,10 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + ++ if (cmd.attr.port_num < rdma_start_port(ib_dev) || ++ cmd.attr.port_num > rdma_end_port(ib_dev)) ++ return -EINVAL; ++ + uobj = kmalloc(sizeof *uobj, GFP_KERNEL); + if (!uobj) + return -ENOMEM; +diff --git a/drivers/md/md.c b/drivers/md/md.c +index eff554a12fb4..0a856cb181e9 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -1866,7 +1866,7 @@ super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) + } + sb = page_address(rdev->sb_page); + sb->data_size = cpu_to_le64(num_sectors); +- sb->super_offset = rdev->sb_start; ++ sb->super_offset = cpu_to_le64(rdev->sb_start); + sb->sb_csum = calc_sb_1_csum(sb); + md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, + rdev->sb_page); +@@ -2273,7 +2273,7 @@ static bool does_sb_need_changing(struct mddev *mddev) + /* Check if any mddev parameters have changed */ + if ((mddev->dev_sectors != le64_to_cpu(sb->size)) || + (mddev->reshape_position != le64_to_cpu(sb->reshape_position)) || +- (mddev->layout != le64_to_cpu(sb->layout)) || ++ (mddev->layout != le32_to_cpu(sb->layout)) || + (mddev->raid_disks != le32_to_cpu(sb->raid_disks)) || + (mddev->chunk_sectors != le32_to_cpu(sb->chunksize))) + return true; +diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c +index 8ef6399d794f..bc957528f69f 100644 +--- a/drivers/media/pci/saa7134/saa7134-i2c.c ++++ b/drivers/media/pci/saa7134/saa7134-i2c.c +@@ -355,12 +355,43 @@ static struct i2c_client saa7134_client_template = { + + /* ----------------------------------------------------------- */ + ++/* On Medion 7134 reading EEPROM needs DVB-T demod i2c gate open */ ++static void saa7134_i2c_eeprom_md7134_gate(struct saa7134_dev *dev) ++{ ++ u8 subaddr = 0x7, dmdregval; ++ u8 data[2]; ++ int ret; ++ struct i2c_msg i2cgatemsg_r[] = { {.addr = 0x08, .flags = 0, ++ .buf = &subaddr, .len = 1}, ++ {.addr = 0x08, ++ .flags = I2C_M_RD, ++ .buf = &dmdregval, .len = 1} ++ }; ++ struct i2c_msg i2cgatemsg_w[] = { {.addr = 0x08, .flags = 0, ++ .buf = data, .len = 2} }; ++ ++ ret = i2c_transfer(&dev->i2c_adap, i2cgatemsg_r, 2); ++ if ((ret == 2) && (dmdregval & 0x2)) { ++ pr_debug("%s: DVB-T demod i2c gate was left closed\n", ++ dev->name); ++ ++ data[0] = subaddr; ++ data[1] = (dmdregval & ~0x2); ++ if (i2c_transfer(&dev->i2c_adap, i2cgatemsg_w, 1) != 1) ++ pr_err("%s: EEPROM i2c gate open failure\n", ++ dev->name); ++ } ++} ++ + static int + saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len) + { + unsigned char buf; + int i,err; + ++ if (dev->board == SAA7134_BOARD_MD7134) ++ saa7134_i2c_eeprom_md7134_gate(dev); ++ + dev->i2c_client.addr = 0xa0 >> 1; + buf = 0; + if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) { +diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c +index 70da30095b89..a5e4b4b93d1b 100644 +--- a/drivers/net/ethernet/broadcom/bgmac.c ++++ b/drivers/net/ethernet/broadcom/bgmac.c +@@ -1583,6 +1583,11 @@ static int bgmac_probe(struct bcma_device *core) + dev_warn(&core->dev, "Using random MAC: %pM\n", mac); + } + ++ /* This (reset &) enable is not preset in specs or reference driver but ++ * Broadcom does it in arch PCI code when enabling fake PCI device. ++ */ ++ bcma_core_enable(core, 0); ++ + /* Allocation and references */ + net_dev = alloc_etherdev(sizeof(*bgmac)); + if (!net_dev) +diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c +index 930785a724e1..907fd60c4241 100644 +--- a/drivers/net/wireless/ath/ath10k/pci.c ++++ b/drivers/net/wireless/ath/ath10k/pci.c +@@ -3050,7 +3050,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, + goto err_core_destroy; + } + +- if (QCA_REV_6174(ar)) ++ if (QCA_REV_6174(ar) || QCA_REV_9377(ar)) + ath10k_pci_override_ce_config(ar); + + ret = ath10k_pci_alloc_pipes(ar); +diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c +index d59769e858f4..019d7165a045 100644 +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -2539,7 +2539,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, + + tasklet_hrtimer_init(&data->beacon_timer, + mac80211_hwsim_beacon, +- CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS); ++ CLOCK_MONOTONIC, HRTIMER_MODE_ABS); + + spin_lock_bh(&hwsim_radio_lock); + list_add_tail(&data->list, &hwsim_radios); +diff --git a/drivers/pinctrl/freescale/pinctrl-mxs.c b/drivers/pinctrl/freescale/pinctrl-mxs.c +index 6bbda6b4ab50..5da9c95dccb7 100644 +--- a/drivers/pinctrl/freescale/pinctrl-mxs.c ++++ b/drivers/pinctrl/freescale/pinctrl-mxs.c +@@ -195,6 +195,16 @@ static int mxs_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, + return 0; + } + ++static void mxs_pinctrl_rmwl(u32 value, u32 mask, u8 shift, void __iomem *reg) ++{ ++ u32 tmp; ++ ++ tmp = readl(reg); ++ tmp &= ~(mask << shift); ++ tmp |= value << shift; ++ writel(tmp, reg); ++} ++ + static int mxs_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned selector, + unsigned group) + { +@@ -212,8 +222,7 @@ static int mxs_pinctrl_set_mux(struct pinctrl_dev *pctldev, unsigned selector, + reg += bank * 0x20 + pin / 16 * 0x10; + shift = pin % 16 * 2; + +- writel(0x3 << shift, reg + CLR); +- writel(g->muxsel[i] << shift, reg + SET); ++ mxs_pinctrl_rmwl(g->muxsel[i], 0x3, shift, reg); + } + + return 0; +@@ -280,8 +289,7 @@ static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev, + /* mA */ + if (config & MA_PRESENT) { + shift = pin % 8 * 4; +- writel(0x3 << shift, reg + CLR); +- writel(ma << shift, reg + SET); ++ mxs_pinctrl_rmwl(ma, 0x3, shift, reg); + } + + /* vol */ +diff --git a/drivers/pinctrl/meson/pinctrl-meson8b.c b/drivers/pinctrl/meson/pinctrl-meson8b.c +index 9677807db364..b505b87661f8 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson8b.c ++++ b/drivers/pinctrl/meson/pinctrl-meson8b.c +@@ -732,8 +732,8 @@ static const char * const sdxc_c_groups[] = { + static const char * const nand_groups[] = { + "nand_io", "nand_io_ce0", "nand_io_ce1", + "nand_io_rb0", "nand_ale", "nand_cle", +- "nand_wen_clk", "nand_ren_clk", "nand_dqs0", +- "nand_dqs1" ++ "nand_wen_clk", "nand_ren_clk", "nand_dqs_0", ++ "nand_dqs_1" + }; + + static const char * const nor_groups[] = { +diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c +index 2b0d70217bbd..699efb1a8c45 100644 +--- a/drivers/pinctrl/sh-pfc/core.c ++++ b/drivers/pinctrl/sh-pfc/core.c +@@ -543,6 +543,9 @@ static int sh_pfc_probe(struct platform_device *pdev) + ret = info->ops->init(pfc); + if (ret < 0) + return ret; ++ ++ /* .init() may have overridden pfc->info */ ++ info = pfc->info; + } + + /* Enable dummy states for those platforms without pinctrl support */ +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +index 87a4f44147c1..42ffa8708abc 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +@@ -1102,7 +1102,7 @@ static const u16 pinmux_data[] = { + PINMUX_IPSR_MSEL(IP6_5_3, FMIN_E, SEL_FM_4), + PINMUX_IPSR_DATA(IP6_7_6, AUDIO_CLKOUT), + PINMUX_IPSR_MSEL(IP6_7_6, MSIOF1_SS1_B, SEL_SOF1_1), +- PINMUX_IPSR_MSEL(IP6_5_3, TX2, SEL_SCIF2_0), ++ PINMUX_IPSR_MSEL(IP6_7_6, TX2, SEL_SCIF2_0), + PINMUX_IPSR_MSEL(IP6_7_6, SCIFA2_TXD, SEL_SCIFA2_0), + PINMUX_IPSR_DATA(IP6_9_8, IRQ0), + PINMUX_IPSR_MSEL(IP6_9_8, SCIFB1_RXD_D, SEL_SCIFB1_3), +diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c +index 90b973e15982..a7c81e988656 100644 +--- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c ++++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c +@@ -394,7 +394,7 @@ static const struct sunxi_desc_pin sun8i_a83t_pins[] = { + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 18), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), +- SUNXI_FUNCTION(0x3, "owa")), /* DOUT */ ++ SUNXI_FUNCTION(0x3, "spdif")), /* DOUT */ + SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 19), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out")), +diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c +index 7b4af519e17e..8fed55342b0f 100644 +--- a/drivers/staging/comedi/comedi_fops.c ++++ b/drivers/staging/comedi/comedi_fops.c +@@ -2911,6 +2911,7 @@ static int __init comedi_init(void) + dev = comedi_alloc_board_minor(NULL); + if (IS_ERR(dev)) { + comedi_cleanup_board_minors(); ++ class_destroy(comedi_class); + cdev_del(&comedi_cdev); + unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), + COMEDI_NUM_MINORS); +diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c +index 01e642db311e..f35ee85f61b5 100644 +--- a/drivers/staging/vt6656/main_usb.c ++++ b/drivers/staging/vt6656/main_usb.c +@@ -529,6 +529,9 @@ static int vnt_start(struct ieee80211_hw *hw) + goto free_all; + } + ++ if (vnt_key_init_table(priv)) ++ goto free_all; ++ + priv->int_interval = 1; /* bInterval is set to 1 */ + + vnt_int_start_interrupt(priv); +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 96b21b0dac1e..3116edfcdc18 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -223,6 +223,10 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Blackmagic Design UltraStudio SDI */ + { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM }, + ++ /* Hauppauge HVR-950q */ ++ { USB_DEVICE(0x2040, 0x7200), .driver_info = ++ USB_QUIRK_CONFIG_INTF_STRINGS }, ++ + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + +diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c +index 5c0adb9c6fb2..81db2fa08cad 100644 +--- a/drivers/usb/dwc3/dwc3-st.c ++++ b/drivers/usb/dwc3/dwc3-st.c +@@ -224,7 +224,7 @@ static int st_dwc3_probe(struct platform_device *pdev) + + dwc3_data->syscfg_reg_off = res->start; + +- dev_vdbg(&pdev->dev, "glue-logic addr 0x%p, syscfg-reg offset 0x%x\n", ++ dev_vdbg(&pdev->dev, "glue-logic addr 0x%pK, syscfg-reg offset 0x%x\n", + dwc3_data->glue_base, dwc3_data->syscfg_reg_off); + + dwc3_data->rstc_pwrdn = devm_reset_control_get(dev, "powerdown"); +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index ec7a50f98f57..d3bd1afd6302 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1219,7 +1219,7 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, + goto out; + } + +- if (WARN(req->dep != dep, "request %p belongs to '%s'\n", ++ if (WARN(req->dep != dep, "request %pK belongs to '%s'\n", + request, req->dep->name)) { + ret = -EINVAL; + goto out; +@@ -1264,7 +1264,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, + dwc3_stop_active_transfer(dwc, dep->number, true); + goto out1; + } +- dev_err(dwc->dev, "request %p was not queued to %s\n", ++ dev_err(dwc->dev, "request %pK was not queued to %s\n", + request, ep->name); + ret = -EINVAL; + goto out0; +@@ -1866,7 +1866,7 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, + * would help. Lets hope that if this occurs, someone + * fixes the root cause instead of looking away :) + */ +- dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n", ++ dev_err(dwc->dev, "%s's TRB (%pK) still owned by HW\n", + dep->name, trb); + count = trb->size & DWC3_TRB_SIZE_MASK; + +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index 33cec50978b8..b0dc6da3d970 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -134,6 +134,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ + { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ + { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ ++ { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */ + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 3bf61acfc26b..ebe51f11105d 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1877,6 +1877,10 @@ static const struct usb_device_id option_ids[] = { + .driver_info = (kernel_ulong_t)&four_g_w100_blacklist + }, + { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800, 0xff) }, ++ { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9801, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) }, + { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, +diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c +index fd509ed6cf70..652b4334b26d 100644 +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -158,6 +158,7 @@ static const struct usb_device_id id_table[] = { + {DEVICE_SWI(0x1199, 0x9056)}, /* Sierra Wireless Modem */ + {DEVICE_SWI(0x1199, 0x9060)}, /* Sierra Wireless Modem */ + {DEVICE_SWI(0x1199, 0x9061)}, /* Sierra Wireless Modem */ ++ {DEVICE_SWI(0x1199, 0x9063)}, /* Sierra Wireless EM7305 */ + {DEVICE_SWI(0x1199, 0x9070)}, /* Sierra Wireless MC74xx */ + {DEVICE_SWI(0x1199, 0x9071)}, /* Sierra Wireless MC74xx */ + {DEVICE_SWI(0x1199, 0x9078)}, /* Sierra Wireless EM74xx */ +diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c +index 44ab43fc4fcc..af10f7b131a4 100644 +--- a/drivers/usb/usbip/stub_main.c ++++ b/drivers/usb/usbip/stub_main.c +@@ -262,7 +262,11 @@ void stub_device_cleanup_urbs(struct stub_device *sdev) + kmem_cache_free(stub_priv_cache, priv); + + kfree(urb->transfer_buffer); ++ urb->transfer_buffer = NULL; ++ + kfree(urb->setup_packet); ++ urb->setup_packet = NULL; ++ + usb_free_urb(urb); + } + } +diff --git a/drivers/usb/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c +index dbcabc9dbe0d..021003c4de53 100644 +--- a/drivers/usb/usbip/stub_tx.c ++++ b/drivers/usb/usbip/stub_tx.c +@@ -28,7 +28,11 @@ static void stub_free_priv_and_urb(struct stub_priv *priv) + struct urb *urb = priv->urb; + + kfree(urb->setup_packet); ++ urb->setup_packet = NULL; ++ + kfree(urb->transfer_buffer); ++ urb->transfer_buffer = NULL; ++ + list_del(&priv->list); + kmem_cache_free(stub_priv_cache, priv); + usb_free_urb(urb); +diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c +index 5d09ea585840..c2ee23acf359 100644 +--- a/fs/ext4/sysfs.c ++++ b/fs/ext4/sysfs.c +@@ -100,7 +100,7 @@ static ssize_t reserved_clusters_store(struct ext4_attr *a, + int ret; + + ret = kstrtoull(skip_spaces(buf), 0, &val); +- if (!ret || val >= clusters) ++ if (ret || val >= clusters) + return -EINVAL; + + atomic64_set(&sbi->s_resv_clusters, val); +diff --git a/fs/fcntl.c b/fs/fcntl.c +index ee85cd4e136a..62376451bbce 100644 +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -740,16 +740,10 @@ static int __init fcntl_init(void) + * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY + * is defined as O_NONBLOCK on some platforms and not on others. + */ +- BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( +- O_RDONLY | O_WRONLY | O_RDWR | +- O_CREAT | O_EXCL | O_NOCTTY | +- O_TRUNC | O_APPEND | /* O_NONBLOCK | */ +- __O_SYNC | O_DSYNC | FASYNC | +- O_DIRECT | O_LARGEFILE | O_DIRECTORY | +- O_NOFOLLOW | O_NOATIME | O_CLOEXEC | +- __FMODE_EXEC | O_PATH | __O_TMPFILE | +- __FMODE_NONOTIFY +- )); ++ BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ != ++ HWEIGHT32( ++ (VALID_OPEN_FLAGS & ~(O_NONBLOCK | O_NDELAY)) | ++ __FMODE_EXEC | __FMODE_NONOTIFY)); + + fasync_cache = kmem_cache_create("fasync_cache", + sizeof(struct fasync_struct), 0, SLAB_PANIC, NULL); +diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c +index 9cd8c92b953d..070901e76653 100644 +--- a/fs/gfs2/glock.c ++++ b/fs/gfs2/glock.c +@@ -80,9 +80,9 @@ static struct rhashtable_params ht_parms = { + + static struct rhashtable gl_hash_table; + +-void gfs2_glock_free(struct gfs2_glock *gl) ++static void gfs2_glock_dealloc(struct rcu_head *rcu) + { +- struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; ++ struct gfs2_glock *gl = container_of(rcu, struct gfs2_glock, gl_rcu); + + if (gl->gl_ops->go_flags & GLOF_ASPACE) { + kmem_cache_free(gfs2_glock_aspace_cachep, gl); +@@ -90,6 +90,13 @@ void gfs2_glock_free(struct gfs2_glock *gl) + kfree(gl->gl_lksb.sb_lvbptr); + kmem_cache_free(gfs2_glock_cachep, gl); + } ++} ++ ++void gfs2_glock_free(struct gfs2_glock *gl) ++{ ++ struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; ++ ++ call_rcu(&gl->gl_rcu, gfs2_glock_dealloc); + if (atomic_dec_and_test(&sdp->sd_glock_disposal)) + wake_up(&sdp->sd_glock_wait); + } +diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h +index be519416c112..4a9077ec9313 100644 +--- a/fs/gfs2/incore.h ++++ b/fs/gfs2/incore.h +@@ -367,6 +367,7 @@ struct gfs2_glock { + loff_t end; + } gl_vm; + }; ++ struct rcu_head gl_rcu; + struct rhash_head gl_node; + }; + +diff --git a/fs/open.c b/fs/open.c +index 157b9940dd73..fbc5c7b230b3 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -885,6 +885,12 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o + int lookup_flags = 0; + int acc_mode; + ++ /* ++ * Clear out all open flags we don't know about so that we don't report ++ * them in fcntl(F_GETFD) or similar interfaces. ++ */ ++ flags &= VALID_OPEN_FLAGS; ++ + if (flags & (O_CREAT | __O_TMPFILE)) + op->mode = (mode & S_IALLUGO) | S_IFREG; + else +diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h +index 76ce329e656d..1b48d9c9a561 100644 +--- a/include/linux/fcntl.h ++++ b/include/linux/fcntl.h +@@ -3,6 +3,12 @@ + + #include <uapi/linux/fcntl.h> + ++/* list of all valid flags for the open/openat flags argument: */ ++#define VALID_OPEN_FLAGS \ ++ (O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | \ ++ O_APPEND | O_NDELAY | O_NONBLOCK | O_NDELAY | __O_SYNC | O_DSYNC | \ ++ FASYNC | O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \ ++ O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE) + + #ifndef force_o_largefile + #define force_o_largefile() (BITS_PER_LONG != 32) +diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h +index 3993b21f3d11..757c554408ce 100644 +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -560,9 +560,9 @@ extern void usb_ep0_reinit(struct usb_device *); + ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) + + #define EndpointRequest \ +- ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) ++ ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) + #define EndpointOutRequest \ +- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) ++ ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) + + /* class requests from the USB 2.0 hub spec, table 11-15 */ + /* GetBusState and SetHubDescriptor are optional, omitted */ +diff --git a/ipc/mqueue.c b/ipc/mqueue.c +index 161a1807e6ef..5e24eb0ab5dd 100644 +--- a/ipc/mqueue.c ++++ b/ipc/mqueue.c +@@ -1251,8 +1251,10 @@ retry: + + timeo = MAX_SCHEDULE_TIMEOUT; + ret = netlink_attachskb(sock, nc, &timeo, NULL); +- if (ret == 1) ++ if (ret == 1) { ++ sock = NULL; + goto retry; ++ } + if (ret) { + sock = NULL; + nc = NULL; +diff --git a/kernel/sysctl.c b/kernel/sysctl.c +index 464a7864e4c5..002ec084124b 100644 +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -2067,9 +2067,12 @@ static int do_proc_douintvec_conv(bool *negp, unsigned long *lvalp, + if (write) { + if (*negp) + return -EINVAL; ++ if (*lvalp > UINT_MAX) ++ return -EINVAL; + *valp = *lvalp; + } else { + unsigned int val = *valp; ++ *negp = false; + *lvalp = (unsigned long)val; + } + return 0; +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index 12ea4ea619ee..e9092a0247bf 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -659,30 +659,25 @@ static int create_trace_kprobe(int argc, char **argv) + pr_info("Probe point is not specified.\n"); + return -EINVAL; + } +- if (isdigit(argv[1][0])) { +- if (is_return) { +- pr_info("Return probe point must be a symbol.\n"); +- return -EINVAL; +- } +- /* an address specified */ +- ret = kstrtoul(&argv[1][0], 0, (unsigned long *)&addr); +- if (ret) { +- pr_info("Failed to parse address.\n"); +- return ret; +- } +- } else { ++ ++ /* try to parse an address. if that fails, try to read the ++ * input as a symbol. */ ++ if (kstrtoul(argv[1], 0, (unsigned long *)&addr)) { + /* a symbol specified */ + symbol = argv[1]; + /* TODO: support .init module functions */ + ret = traceprobe_split_symbol_offset(symbol, &offset); + if (ret) { +- pr_info("Failed to parse symbol.\n"); ++ pr_info("Failed to parse either an address or a symbol.\n"); + return ret; + } + if (offset && is_return) { + pr_info("Return probe must be used without offset.\n"); + return -EINVAL; + } ++ } else if (is_return) { ++ pr_info("Return probe point must be a symbol.\n"); ++ return -EINVAL; + } + argc -= 2; argv += 2; + +diff --git a/mm/vmscan.c b/mm/vmscan.c +index bfc5050cbd01..440c2df9be82 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -2529,7 +2529,7 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc) + if (!populated_zone(zone)) + continue; + +- classzone_idx = requested_highidx; ++ classzone_idx = gfp_zone(sc->gfp_mask); + while (!populated_zone(zone->zone_pgdat->node_zones + + classzone_idx)) + classzone_idx--; +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 87791f803627..8f13b2eaabf8 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -2165,8 +2165,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head) + { + struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *skb; +- int cnt, oldcnt; +- int err; ++ int cnt, oldcnt, lost; + unsigned int mss; + /* Use SACK to deduce losses of new sequences sent during recovery */ + const u32 loss_high = tcp_is_sack(tp) ? tp->snd_nxt : tp->high_seq; +@@ -2206,9 +2205,10 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head) + break; + + mss = tcp_skb_mss(skb); +- err = tcp_fragment(sk, skb, (packets - oldcnt) * mss, +- mss, GFP_ATOMIC); +- if (err < 0) ++ /* If needed, chop off the prefix to mark as lost. */ ++ lost = (packets - oldcnt) * mss; ++ if (lost < skb->len && ++ tcp_fragment(sk, skb, lost, mss, GFP_ATOMIC) < 0) + break; + cnt = packets; + } +diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c +index 696ccfa08d10..31898856682e 100644 +--- a/security/keys/encrypted-keys/encrypted.c ++++ b/security/keys/encrypted-keys/encrypted.c +@@ -428,7 +428,7 @@ static int init_blkcipher_desc(struct blkcipher_desc *desc, const u8 *key, + static struct key *request_master_key(struct encrypted_key_payload *epayload, + const u8 **master_key, size_t *master_keylen) + { +- struct key *mkey = NULL; ++ struct key *mkey = ERR_PTR(-EINVAL); + + if (!strncmp(epayload->master_desc, KEY_TRUSTED_PREFIX, + KEY_TRUSTED_PREFIX_LEN)) { +diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h +index fa7208a32d76..8a679b21f0c4 100644 +--- a/tools/include/linux/compiler.h ++++ b/tools/include/linux/compiler.h +@@ -115,4 +115,13 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s + #define WRITE_ONCE(x, val) \ + ({ union { typeof(x) __val; char __c[1]; } __u = { .__val = (val) }; __write_once_size(&(x), __u.__c, sizeof(x)); __u.__val; }) + ++ ++#ifndef __fallthrough ++# if defined(__GNUC__) && __GNUC__ >= 7 ++# define __fallthrough __attribute__ ((fallthrough)) ++# else ++# define __fallthrough ++# endif ++#endif ++ + #endif /* _TOOLS_LINUX_COMPILER_H */ +diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c +index d28c1b6a3b54..fa5d17af88b7 100644 +--- a/tools/perf/arch/x86/tests/intel-cqm.c ++++ b/tools/perf/arch/x86/tests/intel-cqm.c +@@ -17,7 +17,7 @@ static pid_t spawn(void) + if (pid) + return pid; + +- while(1); ++ while(1) + sleep(5); + return 0; + } +diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c +index 9223c164e545..1f86ee8fb831 100644 +--- a/tools/perf/arch/x86/util/dwarf-regs.c ++++ b/tools/perf/arch/x86/util/dwarf-regs.c +@@ -63,6 +63,8 @@ struct pt_regs_offset { + # define REG_OFFSET_NAME_32(n, r) {.name = n, .offset = offsetof(struct pt_regs, r)} + #endif + ++/* TODO: switching by dwarf address size */ ++#ifndef __x86_64__ + static const struct pt_regs_offset x86_32_regoffset_table[] = { + REG_OFFSET_NAME_32("%ax", eax), + REG_OFFSET_NAME_32("%cx", ecx), +@@ -75,6 +77,8 @@ static const struct pt_regs_offset x86_32_regoffset_table[] = { + REG_OFFSET_END, + }; + ++#define regoffset_table x86_32_regoffset_table ++#else + static const struct pt_regs_offset x86_64_regoffset_table[] = { + REG_OFFSET_NAME_64("%ax", rax), + REG_OFFSET_NAME_64("%dx", rdx), +@@ -95,11 +99,7 @@ static const struct pt_regs_offset x86_64_regoffset_table[] = { + REG_OFFSET_END, + }; + +-/* TODO: switching by dwarf address size */ +-#ifdef __x86_64__ + #define regoffset_table x86_64_regoffset_table +-#else +-#define regoffset_table x86_32_regoffset_table + #endif + + /* Minus 1 for the ending REG_OFFSET_END */ +diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c +index 492df2752a2d..b4eb5b679081 100644 +--- a/tools/perf/bench/numa.c ++++ b/tools/perf/bench/numa.c +@@ -1570,13 +1570,13 @@ static int __bench_numa(const char *name) + "GB/sec,", "total-speed", "GB/sec total speed"); + + if (g->p.show_details >= 2) { +- char tname[32]; ++ char tname[14 + 2 * 10 + 1]; + struct thread_data *td; + for (p = 0; p < g->p.nr_proc; p++) { + for (t = 0; t < g->p.nr_threads; t++) { +- memset(tname, 0, 32); ++ memset(tname, 0, sizeof(tname)); + td = g->threads + p*g->p.nr_threads + t; +- snprintf(tname, 32, "process%d:thread%d", p, t); ++ snprintf(tname, sizeof(tname), "process%d:thread%d", p, t); + print_res(tname, td->speed_gbs, + "GB/sec", "thread-speed", "GB/sec/thread speed"); + print_res(tname, td->system_time_ns / 1e9, +diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c +index 72b5deb4bd79..20f0e27918dd 100644 +--- a/tools/perf/builtin-script.c ++++ b/tools/perf/builtin-script.c +@@ -1252,21 +1252,19 @@ static int is_directory(const char *base_path, const struct dirent *dent) + return S_ISDIR(st.st_mode); + } + +-#define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\ +- while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ +- lang_next) \ +- if ((lang_dirent.d_type == DT_DIR || \ +- (lang_dirent.d_type == DT_UNKNOWN && \ +- is_directory(scripts_path, &lang_dirent))) && \ +- (strcmp(lang_dirent.d_name, ".")) && \ +- (strcmp(lang_dirent.d_name, ".."))) +- +-#define for_each_script(lang_path, lang_dir, script_dirent, script_next)\ +- while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ +- script_next) \ +- if (script_dirent.d_type != DT_DIR && \ +- (script_dirent.d_type != DT_UNKNOWN || \ +- !is_directory(lang_path, &script_dirent))) ++#define for_each_lang(scripts_path, scripts_dir, lang_dirent) \ ++ while ((lang_dirent = readdir(scripts_dir)) != NULL) \ ++ if ((lang_dirent->d_type == DT_DIR || \ ++ (lang_dirent->d_type == DT_UNKNOWN && \ ++ is_directory(scripts_path, lang_dirent))) && \ ++ (strcmp(lang_dirent->d_name, ".")) && \ ++ (strcmp(lang_dirent->d_name, ".."))) ++ ++#define for_each_script(lang_path, lang_dir, script_dirent) \ ++ while ((script_dirent = readdir(lang_dir)) != NULL) \ ++ if (script_dirent->d_type != DT_DIR && \ ++ (script_dirent->d_type != DT_UNKNOWN || \ ++ !is_directory(lang_path, script_dirent))) + + + #define RECORD_SUFFIX "-record" +@@ -1412,7 +1410,7 @@ static int list_available_scripts(const struct option *opt __maybe_unused, + const char *s __maybe_unused, + int unset __maybe_unused) + { +- struct dirent *script_next, *lang_next, script_dirent, lang_dirent; ++ struct dirent *script_dirent, *lang_dirent; + char scripts_path[MAXPATHLEN]; + DIR *scripts_dir, *lang_dir; + char script_path[MAXPATHLEN]; +@@ -1427,19 +1425,19 @@ static int list_available_scripts(const struct option *opt __maybe_unused, + if (!scripts_dir) + return -1; + +- for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { ++ for_each_lang(scripts_path, scripts_dir, lang_dirent) { + snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, +- lang_dirent.d_name); ++ lang_dirent->d_name); + lang_dir = opendir(lang_path); + if (!lang_dir) + continue; + +- for_each_script(lang_path, lang_dir, script_dirent, script_next) { +- script_root = get_script_root(&script_dirent, REPORT_SUFFIX); ++ for_each_script(lang_path, lang_dir, script_dirent) { ++ script_root = get_script_root(script_dirent, REPORT_SUFFIX); + if (script_root) { + desc = script_desc__findnew(script_root); + snprintf(script_path, MAXPATHLEN, "%s/%s", +- lang_path, script_dirent.d_name); ++ lang_path, script_dirent->d_name); + read_script_info(desc, script_path); + free(script_root); + } +@@ -1527,7 +1525,7 @@ static int check_ev_match(char *dir_name, char *scriptname, + */ + int find_scripts(char **scripts_array, char **scripts_path_array) + { +- struct dirent *script_next, *lang_next, script_dirent, lang_dirent; ++ struct dirent *script_dirent, *lang_dirent; + char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; + DIR *scripts_dir, *lang_dir; + struct perf_session *session; +@@ -1550,9 +1548,9 @@ int find_scripts(char **scripts_array, char **scripts_path_array) + return -1; + } + +- for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { ++ for_each_lang(scripts_path, scripts_dir, lang_dirent) { + snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, +- lang_dirent.d_name); ++ lang_dirent->d_name); + #ifdef NO_LIBPERL + if (strstr(lang_path, "perl")) + continue; +@@ -1566,16 +1564,16 @@ int find_scripts(char **scripts_array, char **scripts_path_array) + if (!lang_dir) + continue; + +- for_each_script(lang_path, lang_dir, script_dirent, script_next) { ++ for_each_script(lang_path, lang_dir, script_dirent) { + /* Skip those real time scripts: xxxtop.p[yl] */ +- if (strstr(script_dirent.d_name, "top.")) ++ if (strstr(script_dirent->d_name, "top.")) + continue; + sprintf(scripts_path_array[i], "%s/%s", lang_path, +- script_dirent.d_name); +- temp = strchr(script_dirent.d_name, '.'); ++ script_dirent->d_name); ++ temp = strchr(script_dirent->d_name, '.'); + snprintf(scripts_array[i], +- (temp - script_dirent.d_name) + 1, +- "%s", script_dirent.d_name); ++ (temp - script_dirent->d_name) + 1, ++ "%s", script_dirent->d_name); + + if (check_ev_match(lang_path, + scripts_array[i], session)) +@@ -1593,7 +1591,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array) + + static char *get_script_path(const char *script_root, const char *suffix) + { +- struct dirent *script_next, *lang_next, script_dirent, lang_dirent; ++ struct dirent *script_dirent, *lang_dirent; + char scripts_path[MAXPATHLEN]; + char script_path[MAXPATHLEN]; + DIR *scripts_dir, *lang_dir; +@@ -1606,21 +1604,21 @@ static char *get_script_path(const char *script_root, const char *suffix) + if (!scripts_dir) + return NULL; + +- for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { ++ for_each_lang(scripts_path, scripts_dir, lang_dirent) { + snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, +- lang_dirent.d_name); ++ lang_dirent->d_name); + lang_dir = opendir(lang_path); + if (!lang_dir) + continue; + +- for_each_script(lang_path, lang_dir, script_dirent, script_next) { +- __script_root = get_script_root(&script_dirent, suffix); ++ for_each_script(lang_path, lang_dir, script_dirent) { ++ __script_root = get_script_root(script_dirent, suffix); + if (__script_root && !strcmp(script_root, __script_root)) { + free(__script_root); + closedir(lang_dir); + closedir(scripts_dir); + snprintf(script_path, MAXPATHLEN, "%s/%s", +- lang_path, script_dirent.d_name); ++ lang_path, script_dirent->d_name); + return strdup(script_path); + } + free(__script_root); +diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c +index 7e2e72e6d9d1..4a8a02c302d2 100644 +--- a/tools/perf/builtin-top.c ++++ b/tools/perf/builtin-top.c +@@ -636,7 +636,7 @@ repeat: + case -1: + if (errno == EINTR) + continue; +- /* Fall trhu */ ++ __fallthrough; + default: + c = getc(stdin); + tcsetattr(0, TCSAFLUSH, &save); +diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c +index c783d8fd3a80..ebe7115c751a 100644 +--- a/tools/perf/builtin-trace.c ++++ b/tools/perf/builtin-trace.c +@@ -1617,6 +1617,7 @@ static int trace__process_event(struct trace *trace, struct machine *machine, + color_fprintf(trace->output, PERF_COLOR_RED, + "LOST %" PRIu64 " events!\n", event->lost.lost); + ret = machine__process_lost_event(machine, event, sample); ++ break; + default: + ret = machine__process_event(machine, event, sample); + break; +diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c +index 636d7b42d844..54af2f2e2ee4 100644 +--- a/tools/perf/tests/parse-events.c ++++ b/tools/perf/tests/parse-events.c +@@ -1727,15 +1727,14 @@ static int test_pmu_events(void) + } + + while (!ret && (ent = readdir(dir))) { +-#define MAX_NAME 100 + struct evlist_test e; +- char name[MAX_NAME]; ++ char name[2 * NAME_MAX + 1 + 12 + 3]; + + if (!strcmp(ent->d_name, ".") || + !strcmp(ent->d_name, "..")) + continue; + +- snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name); ++ snprintf(name, sizeof(name), "cpu/event=%s/u", ent->d_name); + + e.name = name; + e.check = test__checkevent_pmu_events; +@@ -1743,11 +1742,10 @@ static int test_pmu_events(void) + ret = test_event(&e); + if (ret) + break; +- snprintf(name, MAX_NAME, "%s:u,cpu/event=%s/u", ent->d_name, ent->d_name); ++ snprintf(name, sizeof(name), "%s:u,cpu/event=%s/u", ent->d_name, ent->d_name); + e.name = name; + e.check = test__checkevent_pmu_events_mix; + ret = test_event(&e); +-#undef MAX_NAME + } + + closedir(dir); +diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c +index d4d7cc27252f..718bd46d47fa 100644 +--- a/tools/perf/ui/browsers/annotate.c ++++ b/tools/perf/ui/browsers/annotate.c +@@ -755,11 +755,11 @@ static int annotate_browser__run(struct annotate_browser *browser, + nd = browser->curr_hot; + break; + case K_UNTAB: +- if (nd != NULL) ++ if (nd != NULL) { + nd = rb_next(nd); + if (nd == NULL) + nd = rb_first(&browser->entries); +- else ++ } else + nd = browser->curr_hot; + break; + case K_F1: +diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c +index 956187bf1a85..26cba64345e3 100644 +--- a/tools/perf/util/event.c ++++ b/tools/perf/util/event.c +@@ -416,7 +416,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, + { + char filename[PATH_MAX]; + DIR *tasks; +- struct dirent dirent, *next; ++ struct dirent *dirent; + pid_t tgid, ppid; + int rc = 0; + +@@ -445,11 +445,11 @@ static int __event__synthesize_thread(union perf_event *comm_event, + return 0; + } + +- while (!readdir_r(tasks, &dirent, &next) && next) { ++ while ((dirent = readdir(tasks)) != NULL) { + char *end; + pid_t _pid; + +- _pid = strtol(dirent.d_name, &end, 10); ++ _pid = strtol(dirent->d_name, &end, 10); + if (*end) + continue; + +@@ -558,7 +558,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, + { + DIR *proc; + char proc_path[PATH_MAX]; +- struct dirent dirent, *next; ++ struct dirent *dirent; + union perf_event *comm_event, *mmap_event, *fork_event; + int err = -1; + +@@ -583,9 +583,9 @@ int perf_event__synthesize_threads(struct perf_tool *tool, + if (proc == NULL) + goto out_free_fork; + +- while (!readdir_r(proc, &dirent, &next) && next) { ++ while ((dirent = readdir(proc)) != NULL) { + char *end; +- pid_t pid = strtol(dirent.d_name, &end, 10); ++ pid_t pid = strtol(dirent->d_name, &end, 10); + + if (*end) /* only interested in proper numerical dirents */ + continue; +diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +index 71df7acf8643..933a509a90f8 100644 +--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c ++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +@@ -22,6 +22,7 @@ + #include <errno.h> + #include <stdint.h> + #include <inttypes.h> ++#include <linux/compiler.h> + + #include "../cache.h" + #include "../util.h" +@@ -1708,6 +1709,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder) + switch (decoder->packet.type) { + case INTEL_PT_TIP_PGD: + decoder->continuous_period = false; ++ __fallthrough; + case INTEL_PT_TIP_PGE: + case INTEL_PT_TIP: + intel_pt_log("ERROR: Unexpected packet\n"); +@@ -1762,6 +1764,8 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder) + decoder->pge = false; + decoder->continuous_period = false; + intel_pt_clear_tx_flags(decoder); ++ __fallthrough; ++ + case INTEL_PT_TNT: + decoder->have_tma = false; + intel_pt_log("ERROR: Unexpected packet\n"); +@@ -1802,6 +1806,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder) + switch (decoder->packet.type) { + case INTEL_PT_TIP_PGD: + decoder->continuous_period = false; ++ __fallthrough; + case INTEL_PT_TIP_PGE: + case INTEL_PT_TIP: + decoder->pge = decoder->packet.type != INTEL_PT_TIP_PGD; +diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c +index b1257c816310..9b2fce25162b 100644 +--- a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c ++++ b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c +@@ -17,6 +17,7 @@ + #include <string.h> + #include <endian.h> + #include <byteswap.h> ++#include <linux/compiler.h> + + #include "intel-pt-pkt-decoder.h" + +@@ -488,6 +489,7 @@ int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf, + case INTEL_PT_FUP: + if (!(packet->count)) + return snprintf(buf, buf_len, "%s no ip", name); ++ __fallthrough; + case INTEL_PT_CYC: + case INTEL_PT_VMCS: + case INTEL_PT_MTC: +diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c +index a35db828bd0d..38304b7e4f81 100644 +--- a/tools/perf/util/parse-events.c ++++ b/tools/perf/util/parse-events.c +@@ -138,11 +138,11 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { + #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) + #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) + +-#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ +- while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ +- if (sys_dirent.d_type == DT_DIR && \ +- (strcmp(sys_dirent.d_name, ".")) && \ +- (strcmp(sys_dirent.d_name, ".."))) ++#define for_each_subsystem(sys_dir, sys_dirent) \ ++ while ((sys_dirent = readdir(sys_dir)) != NULL) \ ++ if (sys_dirent->d_type == DT_DIR && \ ++ (strcmp(sys_dirent->d_name, ".")) && \ ++ (strcmp(sys_dirent->d_name, ".."))) + + static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) + { +@@ -159,12 +159,12 @@ static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) + return 0; + } + +-#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \ +- while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ +- if (evt_dirent.d_type == DT_DIR && \ +- (strcmp(evt_dirent.d_name, ".")) && \ +- (strcmp(evt_dirent.d_name, "..")) && \ +- (!tp_event_has_id(&sys_dirent, &evt_dirent))) ++#define for_each_event(sys_dirent, evt_dir, evt_dirent) \ ++ while ((evt_dirent = readdir(evt_dir)) != NULL) \ ++ if (evt_dirent->d_type == DT_DIR && \ ++ (strcmp(evt_dirent->d_name, ".")) && \ ++ (strcmp(evt_dirent->d_name, "..")) && \ ++ (!tp_event_has_id(sys_dirent, evt_dirent))) + + #define MAX_EVENT_LENGTH 512 + +@@ -173,7 +173,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) + { + struct tracepoint_path *path = NULL; + DIR *sys_dir, *evt_dir; +- struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; ++ struct dirent *sys_dirent, *evt_dirent; + char id_buf[24]; + int fd; + u64 id; +@@ -184,18 +184,18 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) + if (!sys_dir) + return NULL; + +- for_each_subsystem(sys_dir, sys_dirent, sys_next) { ++ for_each_subsystem(sys_dir, sys_dirent) { + + snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, +- sys_dirent.d_name); ++ sys_dirent->d_name); + evt_dir = opendir(dir_path); + if (!evt_dir) + continue; + +- for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { ++ for_each_event(sys_dirent, evt_dir, evt_dirent) { + + snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, +- evt_dirent.d_name); ++ evt_dirent->d_name); + fd = open(evt_path, O_RDONLY); + if (fd < 0) + continue; +@@ -220,9 +220,9 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) + free(path); + return NULL; + } +- strncpy(path->system, sys_dirent.d_name, ++ strncpy(path->system, sys_dirent->d_name, + MAX_EVENT_LENGTH); +- strncpy(path->name, evt_dirent.d_name, ++ strncpy(path->name, evt_dirent->d_name, + MAX_EVENT_LENGTH); + return path; + } +@@ -1629,7 +1629,7 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob, + bool name_only) + { + DIR *sys_dir, *evt_dir; +- struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; ++ struct dirent *sys_dirent, *evt_dirent; + char evt_path[MAXPATHLEN]; + char dir_path[MAXPATHLEN]; + char **evt_list = NULL; +@@ -1647,20 +1647,20 @@ restart: + goto out_close_sys_dir; + } + +- for_each_subsystem(sys_dir, sys_dirent, sys_next) { ++ for_each_subsystem(sys_dir, sys_dirent) { + if (subsys_glob != NULL && +- !strglobmatch(sys_dirent.d_name, subsys_glob)) ++ !strglobmatch(sys_dirent->d_name, subsys_glob)) + continue; + + snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, +- sys_dirent.d_name); ++ sys_dirent->d_name); + evt_dir = opendir(dir_path); + if (!evt_dir) + continue; + +- for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { ++ for_each_event(sys_dirent, evt_dir, evt_dirent) { + if (event_glob != NULL && +- !strglobmatch(evt_dirent.d_name, event_glob)) ++ !strglobmatch(evt_dirent->d_name, event_glob)) + continue; + + if (!evt_num_known) { +@@ -1669,7 +1669,7 @@ restart: + } + + snprintf(evt_path, MAXPATHLEN, "%s:%s", +- sys_dirent.d_name, evt_dirent.d_name); ++ sys_dirent->d_name, evt_dirent->d_name); + + evt_list[evt_i] = strdup(evt_path); + if (evt_list[evt_i] == NULL) +@@ -1722,7 +1722,7 @@ out_close_sys_dir: + int is_valid_tracepoint(const char *event_string) + { + DIR *sys_dir, *evt_dir; +- struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; ++ struct dirent *sys_dirent, *evt_dirent; + char evt_path[MAXPATHLEN]; + char dir_path[MAXPATHLEN]; + +@@ -1730,17 +1730,17 @@ int is_valid_tracepoint(const char *event_string) + if (!sys_dir) + return 0; + +- for_each_subsystem(sys_dir, sys_dirent, sys_next) { ++ for_each_subsystem(sys_dir, sys_dirent) { + + snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path, +- sys_dirent.d_name); ++ sys_dirent->d_name); + evt_dir = opendir(dir_path); + if (!evt_dir) + continue; + +- for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) { ++ for_each_event(sys_dirent, evt_dir, evt_dirent) { + snprintf(evt_path, MAXPATHLEN, "%s:%s", +- sys_dirent.d_name, evt_dirent.d_name); ++ sys_dirent->d_name, evt_dirent->d_name); + if (!strcmp(evt_path, event_string)) { + closedir(evt_dir); + closedir(sys_dir); +diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c +index 6f2a0279476c..593066c68e3d 100644 +--- a/tools/perf/util/pmu.c ++++ b/tools/perf/util/pmu.c +@@ -153,7 +153,7 @@ static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *n + if (fd == -1) + return -1; + +- sret = read(fd, alias->unit, UNIT_MAX_LEN); ++ sret = read(fd, alias->unit, UNIT_MAX_LEN); + if (sret < 0) + goto error; + +diff --git a/tools/perf/util/scripting-engines/Build b/tools/perf/util/scripting-engines/Build +index 6516e220c247..82d28c67e0f3 100644 +--- a/tools/perf/util/scripting-engines/Build ++++ b/tools/perf/util/scripting-engines/Build +@@ -1,6 +1,6 @@ + libperf-$(CONFIG_LIBPERL) += trace-event-perl.o + libperf-$(CONFIG_LIBPYTHON) += trace-event-python.o + +-CFLAGS_trace-event-perl.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default ++CFLAGS_trace-event-perl.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-nested-externs -Wno-undef -Wno-switch-default + + CFLAGS_trace-event-python.o += $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow +diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c +index bcae659b6546..efb53772e0ec 100644 +--- a/tools/perf/util/strfilter.c ++++ b/tools/perf/util/strfilter.c +@@ -269,6 +269,7 @@ static int strfilter_node__sprint(struct strfilter_node *node, char *buf) + len = strfilter_node__sprint_pt(node->l, buf); + if (len < 0) + return len; ++ __fallthrough; + case '!': + if (buf) { + *(buf + len++) = *node->p; +diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c +index fc8781de62db..accb7ece1d3c 100644 +--- a/tools/perf/util/string.c ++++ b/tools/perf/util/string.c +@@ -21,6 +21,8 @@ s64 perf_atoll(const char *str) + case 'b': case 'B': + if (*p) + goto out_err; ++ ++ __fallthrough; + case '\0': + return length; + default: +diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c +index 0a9ae8014729..829508a21448 100644 +--- a/tools/perf/util/thread.c ++++ b/tools/perf/util/thread.c +@@ -227,7 +227,7 @@ void thread__find_cpumode_addr_location(struct thread *thread, + struct addr_location *al) + { + size_t i; +- const u8 const cpumodes[] = { ++ const u8 cpumodes[] = { + PERF_RECORD_MISC_USER, + PERF_RECORD_MISC_KERNEL, + PERF_RECORD_MISC_GUEST_USER, +diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c +index 6ec3c5ca438f..4e666b95b87e 100644 +--- a/tools/perf/util/thread_map.c ++++ b/tools/perf/util/thread_map.c +@@ -92,8 +92,8 @@ struct thread_map *thread_map__new_by_uid(uid_t uid) + { + DIR *proc; + int max_threads = 32, items, i; +- char path[256]; +- struct dirent dirent, *next, **namelist = NULL; ++ char path[NAME_MAX + 1 + 6]; ++ struct dirent *dirent, **namelist = NULL; + struct thread_map *threads = thread_map__alloc(max_threads); + + if (threads == NULL) +@@ -106,16 +106,16 @@ struct thread_map *thread_map__new_by_uid(uid_t uid) + threads->nr = 0; + atomic_set(&threads->refcnt, 1); + +- while (!readdir_r(proc, &dirent, &next) && next) { ++ while ((dirent = readdir(proc)) != NULL) { + char *end; + bool grow = false; + struct stat st; +- pid_t pid = strtol(dirent.d_name, &end, 10); ++ pid_t pid = strtol(dirent->d_name, &end, 10); + + if (*end) /* only interested in proper numerical dirents */ + continue; + +- snprintf(path, sizeof(path), "/proc/%s", dirent.d_name); ++ snprintf(path, sizeof(path), "/proc/%s", dirent->d_name); + + if (stat(path, &st) != 0) + continue; |