diff options
author | Mike Pagano <mpagano@gentoo.org> | 2018-11-10 16:31:26 -0500 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2018-11-14 09:00:41 -0500 |
commit | 968ab2b8ede2eb0f3eddf61c457ab6a1ffbab6ae (patch) | |
tree | 0e8412ce2a9db541745999cc39cd17a46a234445 | |
parent | linux kernel 4.14.79 (diff) | |
download | linux-patches-968ab2b8ede2eb0f3eddf61c457ab6a1ffbab6ae.tar.gz linux-patches-968ab2b8ede2eb0f3eddf61c457ab6a1ffbab6ae.tar.bz2 linux-patches-968ab2b8ede2eb0f3eddf61c457ab6a1ffbab6ae.zip |
Linux patch 4.14.80
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1079_linux-4.14.80.patch | 1098 |
2 files changed, 1102 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 319ee36e..9993abab 100644 --- a/0000_README +++ b/0000_README @@ -359,6 +359,10 @@ Patch: 1078_linux-4.14.79.patch From: http://www.kernel.org Desc: Linux 4.14.79 +Patch: 1079_linux-4.14.80.patch +From: http://www.kernel.org +Desc: Linux 4.14.80 + 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/1079_linux-4.14.80.patch b/1079_linux-4.14.80.patch new file mode 100644 index 00000000..009344bb --- /dev/null +++ b/1079_linux-4.14.80.patch @@ -0,0 +1,1098 @@ +diff --git a/Makefile b/Makefile +index 57a007bf1181..f4cad5e03561 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 14 +-SUBLEVEL = 79 ++SUBLEVEL = 80 + EXTRAVERSION = + NAME = Petit Gorille + +diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi +index 2780e68a853b..914f59166a99 100644 +--- a/arch/arm/boot/dts/tegra20.dtsi ++++ b/arch/arm/boot/dts/tegra20.dtsi +@@ -706,7 +706,7 @@ + phy_type = "ulpi"; + clocks = <&tegra_car TEGRA20_CLK_USB2>, + <&tegra_car TEGRA20_CLK_PLL_U>, +- <&tegra_car TEGRA20_CLK_PLL_P_OUT4>; ++ <&tegra_car TEGRA20_CLK_CDEV2>; + clock-names = "reg", "pll_u", "ulpi-link"; + resets = <&tegra_car 58>, <&tegra_car 22>; + reset-names = "usb", "utmi-pads"; +diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h +index a38bf5a1e37a..69dcdf195b61 100644 +--- a/arch/x86/include/asm/fpu/internal.h ++++ b/arch/x86/include/asm/fpu/internal.h +@@ -528,7 +528,7 @@ static inline void fpregs_activate(struct fpu *fpu) + static inline void + switch_fpu_prepare(struct fpu *old_fpu, int cpu) + { +- if (old_fpu->initialized) { ++ if (static_cpu_has(X86_FEATURE_FPU) && old_fpu->initialized) { + if (!copy_fpregs_to_fpstate(old_fpu)) + old_fpu->last_cpu = -1; + else +diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h +index ba3c523aaf16..12aa2bb6bac4 100644 +--- a/arch/x86/include/asm/percpu.h ++++ b/arch/x86/include/asm/percpu.h +@@ -185,22 +185,22 @@ do { \ + typeof(var) pfo_ret__; \ + switch (sizeof(var)) { \ + case 1: \ +- asm(op "b "__percpu_arg(1)",%0" \ ++ asm volatile(op "b "__percpu_arg(1)",%0"\ + : "=q" (pfo_ret__) \ + : "m" (var)); \ + break; \ + case 2: \ +- asm(op "w "__percpu_arg(1)",%0" \ ++ asm volatile(op "w "__percpu_arg(1)",%0"\ + : "=r" (pfo_ret__) \ + : "m" (var)); \ + break; \ + case 4: \ +- asm(op "l "__percpu_arg(1)",%0" \ ++ asm volatile(op "l "__percpu_arg(1)",%0"\ + : "=r" (pfo_ret__) \ + : "m" (var)); \ + break; \ + case 8: \ +- asm(op "q "__percpu_arg(1)",%0" \ ++ asm volatile(op "q "__percpu_arg(1)",%0"\ + : "=r" (pfo_ret__) \ + : "m" (var)); \ + break; \ +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index dcb00acb6583..4bc12447a50f 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1287,7 +1287,7 @@ void __init setup_arch(char **cmdline_p) + kvm_guest_init(); + + e820__reserve_resources(); +- e820__register_nosave_regions(max_low_pfn); ++ e820__register_nosave_regions(max_pfn); + + x86_init.resources.reserve_resources(); + +diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c +index 49a5c394f3ed..ab0176ae985b 100644 +--- a/arch/x86/kernel/time.c ++++ b/arch/x86/kernel/time.c +@@ -25,7 +25,7 @@ + #include <asm/time.h> + + #ifdef CONFIG_X86_64 +-__visible volatile unsigned long jiffies __cacheline_aligned = INITIAL_JIFFIES; ++__visible volatile unsigned long jiffies __cacheline_aligned_in_smp = INITIAL_JIFFIES; + #endif + + unsigned long profile_pc(struct pt_regs *regs) +diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c +index 0bf06fa3027e..36d02484e384 100644 +--- a/arch/x86/kernel/tsc.c ++++ b/arch/x86/kernel/tsc.c +@@ -60,7 +60,7 @@ struct cyc2ns { + + static DEFINE_PER_CPU_ALIGNED(struct cyc2ns, cyc2ns); + +-void cyc2ns_read_begin(struct cyc2ns_data *data) ++void __always_inline cyc2ns_read_begin(struct cyc2ns_data *data) + { + int seq, idx; + +@@ -77,7 +77,7 @@ void cyc2ns_read_begin(struct cyc2ns_data *data) + } while (unlikely(seq != this_cpu_read(cyc2ns.seq.sequence))); + } + +-void cyc2ns_read_end(void) ++void __always_inline cyc2ns_read_end(void) + { + preempt_enable_notrace(); + } +@@ -123,7 +123,7 @@ static void cyc2ns_init(int cpu) + seqcount_init(&c2n->seq); + } + +-static inline unsigned long long cycles_2_ns(unsigned long long cyc) ++static __always_inline unsigned long long cycles_2_ns(unsigned long long cyc) + { + struct cyc2ns_data data; + unsigned long long ns; +diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c +index 435def22445d..f66395524d0e 100644 +--- a/drivers/gpio/gpio-mxs.c ++++ b/drivers/gpio/gpio-mxs.c +@@ -32,8 +32,6 @@ + #include <linux/platform_device.h> + #include <linux/slab.h> + #include <linux/gpio/driver.h> +-/* FIXME: for gpio_get_value(), replace this by direct register read */ +-#include <linux/gpio.h> + #include <linux/module.h> + + #define MXS_SET 0x4 +@@ -100,7 +98,7 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) + port->both_edges &= ~pin_mask; + switch (type) { + case IRQ_TYPE_EDGE_BOTH: +- val = gpio_get_value(port->gc.base + d->hwirq); ++ val = port->gc.get(&port->gc, d->hwirq); + if (val) + edge = GPIO_INT_FALL_EDGE; + else +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index c29dea895605..d1191ebed072 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -111,6 +111,9 @@ static const struct edid_quirk { + /* AEO model 0 reports 8 bpc, but is a 6 bpc panel */ + { "AEO", 0, EDID_QUIRK_FORCE_6BPC }, + ++ /* BOE model on HP Pavilion 15-n233sl reports 8 bpc, but is a 6 bpc panel */ ++ { "BOE", 0x78b, EDID_QUIRK_FORCE_6BPC }, ++ + /* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */ + { "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC }, + +@@ -4220,7 +4223,7 @@ static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector, + struct drm_hdmi_info *hdmi = &connector->display_info.hdmi; + + dc_mask = db[7] & DRM_EDID_YCBCR420_DC_MASK; +- hdmi->y420_dc_modes |= dc_mask; ++ hdmi->y420_dc_modes = dc_mask; + } + + static void drm_parse_hdmi_forum_vsdb(struct drm_connector *connector, +diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c +index 5e93589c335c..29d1d3df3164 100644 +--- a/drivers/gpu/drm/drm_fb_helper.c ++++ b/drivers/gpu/drm/drm_fb_helper.c +@@ -1490,6 +1490,25 @@ unlock: + } + EXPORT_SYMBOL(drm_fb_helper_ioctl); + ++static bool drm_fb_pixel_format_equal(const struct fb_var_screeninfo *var_1, ++ const struct fb_var_screeninfo *var_2) ++{ ++ return var_1->bits_per_pixel == var_2->bits_per_pixel && ++ var_1->grayscale == var_2->grayscale && ++ var_1->red.offset == var_2->red.offset && ++ var_1->red.length == var_2->red.length && ++ var_1->red.msb_right == var_2->red.msb_right && ++ var_1->green.offset == var_2->green.offset && ++ var_1->green.length == var_2->green.length && ++ var_1->green.msb_right == var_2->green.msb_right && ++ var_1->blue.offset == var_2->blue.offset && ++ var_1->blue.length == var_2->blue.length && ++ var_1->blue.msb_right == var_2->blue.msb_right && ++ var_1->transp.offset == var_2->transp.offset && ++ var_1->transp.length == var_2->transp.length && ++ var_1->transp.msb_right == var_2->transp.msb_right; ++} ++ + /** + * drm_fb_helper_check_var - implementation for &fb_ops.fb_check_var + * @var: screeninfo to check +@@ -1500,7 +1519,6 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, + { + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; +- int depth; + + if (var->pixclock != 0 || in_dbg_master()) + return -EINVAL; +@@ -1520,72 +1538,15 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, + return -EINVAL; + } + +- switch (var->bits_per_pixel) { +- case 16: +- depth = (var->green.length == 6) ? 16 : 15; +- break; +- case 32: +- depth = (var->transp.length > 0) ? 32 : 24; +- break; +- default: +- depth = var->bits_per_pixel; +- break; +- } +- +- switch (depth) { +- case 8: +- var->red.offset = 0; +- var->green.offset = 0; +- var->blue.offset = 0; +- var->red.length = 8; +- var->green.length = 8; +- var->blue.length = 8; +- var->transp.length = 0; +- var->transp.offset = 0; +- break; +- case 15: +- var->red.offset = 10; +- var->green.offset = 5; +- var->blue.offset = 0; +- var->red.length = 5; +- var->green.length = 5; +- var->blue.length = 5; +- var->transp.length = 1; +- var->transp.offset = 15; +- break; +- case 16: +- var->red.offset = 11; +- var->green.offset = 5; +- var->blue.offset = 0; +- var->red.length = 5; +- var->green.length = 6; +- var->blue.length = 5; +- var->transp.length = 0; +- var->transp.offset = 0; +- break; +- case 24: +- var->red.offset = 16; +- var->green.offset = 8; +- var->blue.offset = 0; +- var->red.length = 8; +- var->green.length = 8; +- var->blue.length = 8; +- var->transp.length = 0; +- var->transp.offset = 0; +- break; +- case 32: +- var->red.offset = 16; +- var->green.offset = 8; +- var->blue.offset = 0; +- var->red.length = 8; +- var->green.length = 8; +- var->blue.length = 8; +- var->transp.length = 8; +- var->transp.offset = 24; +- break; +- default: ++ /* ++ * drm fbdev emulation doesn't support changing the pixel format at all, ++ * so reject all pixel format changing requests. ++ */ ++ if (!drm_fb_pixel_format_equal(var, &info->var)) { ++ DRM_DEBUG("fbdev emulation doesn't support changing the pixel format\n"); + return -EINVAL; + } ++ + return 0; + } + EXPORT_SYMBOL(drm_fb_helper_check_var); +diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c +index f2a7f62c2834..09cb24353be3 100644 +--- a/drivers/infiniband/core/ucm.c ++++ b/drivers/infiniband/core/ucm.c +@@ -46,6 +46,8 @@ + #include <linux/mutex.h> + #include <linux/slab.h> + ++#include <linux/nospec.h> ++ + #include <linux/uaccess.h> + + #include <rdma/ib.h> +@@ -1118,6 +1120,7 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf, + + if (hdr.cmd >= ARRAY_SIZE(ucm_cmd_table)) + return -EINVAL; ++ hdr.cmd = array_index_nospec(hdr.cmd, ARRAY_SIZE(ucm_cmd_table)); + + if (hdr.in + sizeof(hdr) > len) + return -EINVAL; +diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c +index 17144a781aeb..c3e5f921da12 100644 +--- a/drivers/infiniband/core/ucma.c ++++ b/drivers/infiniband/core/ucma.c +@@ -44,6 +44,8 @@ + #include <linux/module.h> + #include <linux/nsproxy.h> + ++#include <linux/nospec.h> ++ + #include <rdma/rdma_user_cm.h> + #include <rdma/ib_marshall.h> + #include <rdma/rdma_cm.h> +@@ -1659,6 +1661,7 @@ static ssize_t ucma_write(struct file *filp, const char __user *buf, + + if (hdr.cmd >= ARRAY_SIZE(ucma_cmd_table)) + return -EINVAL; ++ hdr.cmd = array_index_nospec(hdr.cmd, ARRAY_SIZE(ucma_cmd_table)); + + if (hdr.in + sizeof(hdr) > len) + return -EINVAL; +diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c +index 696e540304fd..766d30a7b085 100644 +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -1262,6 +1262,7 @@ static const struct acpi_device_id elan_acpi_id[] = { + { "ELAN0611", 0 }, + { "ELAN0612", 0 }, + { "ELAN0618", 0 }, ++ { "ELAN061C", 0 }, + { "ELAN061D", 0 }, + { "ELAN0622", 0 }, + { "ELAN1000", 0 }, +diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c +index 4cc0b42f2acc..ded48a0c77ee 100644 +--- a/drivers/misc/eeprom/at24.c ++++ b/drivers/misc/eeprom/at24.c +@@ -577,6 +577,23 @@ static void at24_get_pdata(struct device *dev, struct at24_platform_data *chip) + if (device_property_present(dev, "read-only")) + chip->flags |= AT24_FLAG_READONLY; + ++ err = device_property_read_u32(dev, "address-width", &val); ++ if (!err) { ++ switch (val) { ++ case 8: ++ if (chip->flags & AT24_FLAG_ADDR16) ++ dev_warn(dev, "Override address width to be 8, while default is 16\n"); ++ chip->flags &= ~AT24_FLAG_ADDR16; ++ break; ++ case 16: ++ chip->flags |= AT24_FLAG_ADDR16; ++ break; ++ default: ++ dev_warn(dev, "Bad \"address-width\" property: %u\n", ++ val); ++ } ++ } ++ + err = device_property_read_u32(dev, "pagesize", &val); + if (!err) { + chip->page_size = val; +diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +index 753259091b22..28bd4cf61741 100644 +--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c ++++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +@@ -613,9 +613,11 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) + return NETDEV_TX_OK; + } + +-static void fs_timeout(struct net_device *dev) ++static void fs_timeout_work(struct work_struct *work) + { +- struct fs_enet_private *fep = netdev_priv(dev); ++ struct fs_enet_private *fep = container_of(work, struct fs_enet_private, ++ timeout_work); ++ struct net_device *dev = fep->ndev; + unsigned long flags; + int wake = 0; + +@@ -627,7 +629,6 @@ static void fs_timeout(struct net_device *dev) + phy_stop(dev->phydev); + (*fep->ops->stop)(dev); + (*fep->ops->restart)(dev); +- phy_start(dev->phydev); + } + + phy_start(dev->phydev); +@@ -639,6 +640,13 @@ static void fs_timeout(struct net_device *dev) + netif_wake_queue(dev); + } + ++static void fs_timeout(struct net_device *dev) ++{ ++ struct fs_enet_private *fep = netdev_priv(dev); ++ ++ schedule_work(&fep->timeout_work); ++} ++ + /*----------------------------------------------------------------------------- + * generic link-change handler - should be sufficient for most cases + *-----------------------------------------------------------------------------*/ +@@ -759,6 +767,7 @@ static int fs_enet_close(struct net_device *dev) + netif_stop_queue(dev); + netif_carrier_off(dev); + napi_disable(&fep->napi); ++ cancel_work_sync(&fep->timeout_work); + phy_stop(dev->phydev); + + spin_lock_irqsave(&fep->lock, flags); +@@ -1019,6 +1028,7 @@ static int fs_enet_probe(struct platform_device *ofdev) + + ndev->netdev_ops = &fs_enet_netdev_ops; + ndev->watchdog_timeo = 2 * HZ; ++ INIT_WORK(&fep->timeout_work, fs_timeout_work); + netif_napi_add(ndev, &fep->napi, fs_enet_napi, fpi->napi_weight); + + ndev->ethtool_ops = &fs_ethtool_ops; +diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet.h b/drivers/net/ethernet/freescale/fs_enet/fs_enet.h +index 168e10ea487f..837c802ca302 100644 +--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet.h ++++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet.h +@@ -125,6 +125,7 @@ struct fs_enet_private { + spinlock_t lock; /* during all ops except TX pckt processing */ + spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */ + struct fs_platform_info *fpi; ++ struct work_struct timeout_work; + const struct fs_ops *ops; + int rx_ring, tx_ring; + dma_addr_t ring_mem_addr; +diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c +index 51364621f77c..a421d6c551b6 100644 +--- a/drivers/ptp/ptp_chardev.c ++++ b/drivers/ptp/ptp_chardev.c +@@ -24,6 +24,8 @@ + #include <linux/slab.h> + #include <linux/timekeeping.h> + ++#include <linux/nospec.h> ++ + #include "ptp_private.h" + + static int ptp_disable_pinfunc(struct ptp_clock_info *ops, +@@ -248,6 +250,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) + err = -EINVAL; + break; + } ++ pin_index = array_index_nospec(pin_index, ops->n_pins); + if (mutex_lock_interruptible(&ptp->pincfg_mux)) + return -ERESTARTSYS; + pd = ops->pin_config[pin_index]; +@@ -266,6 +269,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) + err = -EINVAL; + break; + } ++ pin_index = array_index_nospec(pin_index, ops->n_pins); + if (mutex_lock_interruptible(&ptp->pincfg_mux)) + return -ERESTARTSYS; + err = ptp_set_pinfunc(ptp, pin_index, pd.func, pd.chan); +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 9f6f402470ac..e41d00bc7e97 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -322,17 +322,17 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf) + + if (difference & ACM_CTRL_DSR) + acm->iocount.dsr++; +- if (difference & ACM_CTRL_BRK) +- acm->iocount.brk++; +- if (difference & ACM_CTRL_RI) +- acm->iocount.rng++; + if (difference & ACM_CTRL_DCD) + acm->iocount.dcd++; +- if (difference & ACM_CTRL_FRAMING) ++ if (newctrl & ACM_CTRL_BRK) ++ acm->iocount.brk++; ++ if (newctrl & ACM_CTRL_RI) ++ acm->iocount.rng++; ++ if (newctrl & ACM_CTRL_FRAMING) + acm->iocount.frame++; +- if (difference & ACM_CTRL_PARITY) ++ if (newctrl & ACM_CTRL_PARITY) + acm->iocount.parity++; +- if (difference & ACM_CTRL_OVERRUN) ++ if (newctrl & ACM_CTRL_OVERRUN) + acm->iocount.overrun++; + spin_unlock(&acm->read_lock); + +@@ -367,7 +367,6 @@ static void acm_ctrl_irq(struct urb *urb) + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ +- acm->nb_index = 0; + dev_dbg(&acm->control->dev, + "%s - urb shutting down with status: %d\n", + __func__, status); +@@ -1655,6 +1654,7 @@ static int acm_pre_reset(struct usb_interface *intf) + struct acm *acm = usb_get_intfdata(intf); + + clear_bit(EVENT_RX_STALL, &acm->flags); ++ acm->nb_index = 0; /* pending control transfers are lost */ + + return 0; + } +diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c +index 76cb9b3649b4..492977f78fde 100644 +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -1491,8 +1491,6 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb + u = 0; + switch (uurb->type) { + case USBDEVFS_URB_TYPE_CONTROL: +- if (is_in) +- allow_short = true; + if (!usb_endpoint_xfer_control(&ep->desc)) + return -EINVAL; + /* min 8 byte setup packet */ +@@ -1522,6 +1520,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb + is_in = 0; + uurb->endpoint &= ~USB_DIR_IN; + } ++ if (is_in) ++ allow_short = true; + snoop(&ps->dev->dev, "control urb: bRequestType=%02x " + "bRequest=%02x wValue=%04x " + "wIndex=%04x wLength=%04x\n", +diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c +index 5153e29870c3..25ba30329533 100644 +--- a/drivers/usb/gadget/function/f_mass_storage.c ++++ b/drivers/usb/gadget/function/f_mass_storage.c +@@ -221,6 +221,8 @@ + #include <linux/usb/gadget.h> + #include <linux/usb/composite.h> + ++#include <linux/nospec.h> ++ + #include "configfs.h" + + +@@ -3170,6 +3172,7 @@ static struct config_group *fsg_lun_make(struct config_group *group, + fsg_opts = to_fsg_opts(&group->cg_item); + if (num >= FSG_MAX_LUNS) + return ERR_PTR(-ERANGE); ++ num = array_index_nospec(num, FSG_MAX_LUNS); + + mutex_lock(&fsg_opts->lock); + if (fsg_opts->refcnt || fsg_opts->common->luns[num]) { +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 0600dadd6a0c..392fddc80c44 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -564,6 +564,9 @@ static void option_instat_callback(struct urb *urb); + /* Interface is reserved */ + #define RSVD(ifnum) ((BIT(ifnum) & 0xff) << 0) + ++/* Interface must have two endpoints */ ++#define NUMEP2 BIT(16) ++ + + static const struct usb_device_id option_ids[] = { + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, +@@ -1084,8 +1087,9 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(4) }, + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), + .driver_info = RSVD(4) }, +- { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06), +- .driver_info = RSVD(4) | RSVD(5) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), ++ .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), +@@ -2010,6 +2014,13 @@ static int option_probe(struct usb_serial *serial, + iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) + return -ENODEV; + ++ /* ++ * Allow matching on bNumEndpoints for devices whose interface numbers ++ * can change (e.g. Quectel EP06). ++ */ ++ if (device_flags & NUMEP2 && iface_desc->bNumEndpoints != 2) ++ return -ENODEV; ++ + /* Store the device flags so we can use them during attach. */ + usb_set_serial_data(serial, (void *)device_flags); + +diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c +index 05aa1ba351b6..84e2d7edaa5c 100644 +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -332,8 +332,9 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + struct vhci_hcd *vhci_hcd; + struct vhci *vhci; + int retval = 0; +- int rhport; ++ int rhport = -1; + unsigned long flags; ++ bool invalid_rhport = false; + + u32 prev_port_status[VHCI_HC_PORTS]; + +@@ -348,9 +349,19 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, + wIndex); + +- if (wIndex > VHCI_HC_PORTS) +- pr_err("invalid port number %d\n", wIndex); +- rhport = wIndex - 1; ++ /* ++ * wIndex can be 0 for some request types (typeReq). rhport is ++ * in valid range when wIndex >= 1 and < VHCI_HC_PORTS. ++ * ++ * Reference port_status[] only with valid rhport when ++ * invalid_rhport is false. ++ */ ++ if (wIndex < 1 || wIndex > VHCI_HC_PORTS) { ++ invalid_rhport = true; ++ if (wIndex > VHCI_HC_PORTS) ++ pr_err("invalid port number %d\n", wIndex); ++ } else ++ rhport = wIndex - 1; + + vhci_hcd = hcd_to_vhci_hcd(hcd); + vhci = vhci_hcd->vhci; +@@ -359,8 +370,9 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + + /* store old status and compare now and old later */ + if (usbip_dbg_flag_vhci_rh) { +- memcpy(prev_port_status, vhci_hcd->port_status, +- sizeof(prev_port_status)); ++ if (!invalid_rhport) ++ memcpy(prev_port_status, vhci_hcd->port_status, ++ sizeof(prev_port_status)); + } + + switch (typeReq) { +@@ -368,8 +380,10 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + usbip_dbg_vhci_rh(" ClearHubFeature\n"); + break; + case ClearPortFeature: +- if (rhport < 0) ++ if (invalid_rhport) { ++ pr_err("invalid port number %d\n", wIndex); + goto error; ++ } + switch (wValue) { + case USB_PORT_FEAT_SUSPEND: + if (hcd->speed == HCD_USB3) { +@@ -429,9 +443,10 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + break; + case GetPortStatus: + usbip_dbg_vhci_rh(" GetPortStatus port %x\n", wIndex); +- if (wIndex < 1) { ++ if (invalid_rhport) { + pr_err("invalid port number %d\n", wIndex); + retval = -EPIPE; ++ goto error; + } + + /* we do not care about resume. */ +@@ -527,16 +542,20 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + goto error; + } + +- if (rhport < 0) ++ if (invalid_rhport) { ++ pr_err("invalid port number %d\n", wIndex); + goto error; ++ } + + vhci_hcd->port_status[rhport] |= USB_PORT_STAT_SUSPEND; + break; + case USB_PORT_FEAT_POWER: + usbip_dbg_vhci_rh( + " SetPortFeature: USB_PORT_FEAT_POWER\n"); +- if (rhport < 0) ++ if (invalid_rhport) { ++ pr_err("invalid port number %d\n", wIndex); + goto error; ++ } + if (hcd->speed == HCD_USB3) + vhci_hcd->port_status[rhport] |= USB_SS_PORT_STAT_POWER; + else +@@ -545,8 +564,10 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + case USB_PORT_FEAT_BH_PORT_RESET: + usbip_dbg_vhci_rh( + " SetPortFeature: USB_PORT_FEAT_BH_PORT_RESET\n"); +- if (rhport < 0) ++ if (invalid_rhport) { ++ pr_err("invalid port number %d\n", wIndex); + goto error; ++ } + /* Applicable only for USB3.0 hub */ + if (hcd->speed != HCD_USB3) { + pr_err("USB_PORT_FEAT_BH_PORT_RESET req not " +@@ -557,8 +578,10 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + case USB_PORT_FEAT_RESET: + usbip_dbg_vhci_rh( + " SetPortFeature: USB_PORT_FEAT_RESET\n"); +- if (rhport < 0) ++ if (invalid_rhport) { ++ pr_err("invalid port number %d\n", wIndex); + goto error; ++ } + /* if it's already enabled, disable */ + if (hcd->speed == HCD_USB3) { + vhci_hcd->port_status[rhport] = 0; +@@ -579,8 +602,10 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + default: + usbip_dbg_vhci_rh(" SetPortFeature: default %d\n", + wValue); +- if (rhport < 0) ++ if (invalid_rhport) { ++ pr_err("invalid port number %d\n", wIndex); + goto error; ++ } + if (hcd->speed == HCD_USB3) { + if ((vhci_hcd->port_status[rhport] & + USB_SS_PORT_STAT_POWER) != 0) { +@@ -622,7 +647,7 @@ error: + if (usbip_dbg_flag_vhci_rh) { + pr_debug("port %d\n", rhport); + /* Only dump valid port status */ +- if (rhport >= 0) { ++ if (!invalid_rhport) { + dump_port_status_diff(prev_port_status[rhport], + vhci_hcd->port_status[rhport], + hcd->speed == HCD_USB3); +@@ -632,8 +657,10 @@ error: + + spin_unlock_irqrestore(&vhci->lock, flags); + +- if ((vhci_hcd->port_status[rhport] & PORT_C_MASK) != 0) ++ if (!invalid_rhport && ++ (vhci_hcd->port_status[rhport] & PORT_C_MASK) != 0) { + usb_hcd_poll_rh_status(hcd); ++ } + + return retval; + } +diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c +index 5f2f67d220fa..f6ed795f4af6 100644 +--- a/fs/cachefiles/namei.c ++++ b/fs/cachefiles/namei.c +@@ -340,7 +340,7 @@ try_again: + trap = lock_rename(cache->graveyard, dir); + + /* do some checks before getting the grave dentry */ +- if (rep->d_parent != dir) { ++ if (rep->d_parent != dir || IS_DEADDIR(d_inode(rep))) { + /* the entry was probably culled when we dropped the parent dir + * lock */ + unlock_rename(cache->graveyard, dir); +diff --git a/fs/ioctl.c b/fs/ioctl.c +index 5ace7efb0d04..9db5ddaf7ef0 100644 +--- a/fs/ioctl.c ++++ b/fs/ioctl.c +@@ -229,7 +229,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd, + ret = -EXDEV; + if (src_file.file->f_path.mnt != dst_file->f_path.mnt) + goto fdput; +- ret = do_clone_file_range(src_file.file, off, dst_file, destoff, olen); ++ ret = vfs_clone_file_range(src_file.file, off, dst_file, destoff, olen); + fdput: + fdput(src_file); + return ret; +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index a3c9bfa77def..f55527ef21e8 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -541,7 +541,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp, + __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst, + u64 dst_pos, u64 count) + { +- return nfserrno(do_clone_file_range(src, src_pos, dst, dst_pos, count)); ++ return nfserrno(vfs_clone_file_range(src, src_pos, dst, dst_pos, ++ count)); + } + + ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst, +diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c +index d76c81323dc1..2bc61e7543dd 100644 +--- a/fs/notify/fsnotify.c ++++ b/fs/notify/fsnotify.c +@@ -286,17 +286,13 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, + + iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu); + +- if ((mask & FS_MODIFY) || +- (test_mask & to_tell->i_fsnotify_mask)) { +- inode_conn = srcu_dereference(to_tell->i_fsnotify_marks, ++ inode_conn = srcu_dereference(to_tell->i_fsnotify_marks, ++ &fsnotify_mark_srcu); ++ if (inode_conn) ++ inode_node = srcu_dereference(inode_conn->list.first, + &fsnotify_mark_srcu); +- if (inode_conn) +- inode_node = srcu_dereference(inode_conn->list.first, +- &fsnotify_mark_srcu); +- } + +- if (mnt && ((mask & FS_MODIFY) || +- (test_mask & mnt->mnt_fsnotify_mask))) { ++ if (mnt) { + inode_conn = srcu_dereference(to_tell->i_fsnotify_marks, + &fsnotify_mark_srcu); + if (inode_conn) +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index c441f9387a1b..321eae740148 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -157,7 +157,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len) + } + + /* Try to use clone_file_range to clone up within the same fs */ +- error = vfs_clone_file_range(old_file, 0, new_file, 0, len); ++ error = do_clone_file_range(old_file, 0, new_file, 0, len); + if (!error) + goto out; + /* Couldn't clone, so now we try to copy the data */ +diff --git a/fs/read_write.c b/fs/read_write.c +index 0046d72efe94..57a00ef895b2 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -1812,8 +1812,8 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, + } + EXPORT_SYMBOL(vfs_clone_file_prep_inodes); + +-int vfs_clone_file_range(struct file *file_in, loff_t pos_in, +- struct file *file_out, loff_t pos_out, u64 len) ++int do_clone_file_range(struct file *file_in, loff_t pos_in, ++ struct file *file_out, loff_t pos_out, u64 len) + { + struct inode *inode_in = file_inode(file_in); + struct inode *inode_out = file_inode(file_out); +@@ -1860,6 +1860,19 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in, + + return ret; + } ++EXPORT_SYMBOL(do_clone_file_range); ++ ++int vfs_clone_file_range(struct file *file_in, loff_t pos_in, ++ struct file *file_out, loff_t pos_out, u64 len) ++{ ++ int ret; ++ ++ file_start_write(file_out); ++ ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len); ++ file_end_write(file_out); ++ ++ return ret; ++} + EXPORT_SYMBOL(vfs_clone_file_range); + + /* +diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c +index 6bd916bd35e2..48eff18c5496 100644 +--- a/fs/xfs/libxfs/xfs_trans_resv.c ++++ b/fs/xfs/libxfs/xfs_trans_resv.c +@@ -232,8 +232,6 @@ xfs_calc_write_reservation( + * the super block to reflect the freed blocks: sector size + * worst case split in allocation btrees per extent assuming 4 extents: + * 4 exts * 2 trees * (2 * max depth - 1) * block size +- * the inode btree: max depth * blocksize +- * the allocation btrees: 2 trees * (max depth - 1) * block size + */ + STATIC uint + xfs_calc_itruncate_reservation( +@@ -245,12 +243,7 @@ xfs_calc_itruncate_reservation( + XFS_FSB_TO_B(mp, 1))), + (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), +- XFS_FSB_TO_B(mp, 1)) + +- xfs_calc_buf_res(5, 0) + +- xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), +- XFS_FSB_TO_B(mp, 1)) + +- xfs_calc_buf_res(2 + mp->m_ialloc_blks + +- mp->m_in_maxlevels, 0))); ++ XFS_FSB_TO_B(mp, 1)))); + } + + /* +diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h +index a992434ded99..267e0426c479 100644 +--- a/include/drm/drm_edid.h ++++ b/include/drm/drm_edid.h +@@ -214,9 +214,9 @@ struct detailed_timing { + #define DRM_EDID_HDMI_DC_Y444 (1 << 3) + + /* YCBCR 420 deep color modes */ +-#define DRM_EDID_YCBCR420_DC_48 (1 << 6) +-#define DRM_EDID_YCBCR420_DC_36 (1 << 5) +-#define DRM_EDID_YCBCR420_DC_30 (1 << 4) ++#define DRM_EDID_YCBCR420_DC_48 (1 << 2) ++#define DRM_EDID_YCBCR420_DC_36 (1 << 1) ++#define DRM_EDID_YCBCR420_DC_30 (1 << 0) + #define DRM_EDID_YCBCR420_DC_MASK (DRM_EDID_YCBCR420_DC_48 | \ + DRM_EDID_YCBCR420_DC_36 | \ + DRM_EDID_YCBCR420_DC_30) +diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h +index 73bec75b74c8..a3333004fd2b 100644 +--- a/include/linux/bpf_verifier.h ++++ b/include/linux/bpf_verifier.h +@@ -50,6 +50,9 @@ struct bpf_reg_state { + * PTR_TO_MAP_VALUE_OR_NULL + */ + struct bpf_map *map_ptr; ++ ++ /* Max size from any of the above. */ ++ unsigned long raw; + }; + /* Fixed part of pointer offset, pointer types only */ + s32 off; +diff --git a/include/linux/fs.h b/include/linux/fs.h +index cc613f20e5a6..7374639f0aa0 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1792,8 +1792,10 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, + extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, + struct inode *inode_out, loff_t pos_out, + u64 *len, bool is_dedupe); ++extern int do_clone_file_range(struct file *file_in, loff_t pos_in, ++ struct file *file_out, loff_t pos_out, u64 len); + extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, +- struct file *file_out, loff_t pos_out, u64 len); ++ struct file *file_out, loff_t pos_out, u64 len); + extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, + struct inode *dest, loff_t destoff, + loff_t len, bool *is_same); +@@ -2712,19 +2714,6 @@ static inline void file_end_write(struct file *file) + __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); + } + +-static inline int do_clone_file_range(struct file *file_in, loff_t pos_in, +- struct file *file_out, loff_t pos_out, +- u64 len) +-{ +- int ret; +- +- file_start_write(file_out); +- ret = vfs_clone_file_range(file_in, pos_in, file_out, pos_out, len); +- file_end_write(file_out); +- +- return ret; +-} +- + /* + * get_write_access() gets write permission for a file. + * put_write_access() releases this write permission. +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index a0ffc62e7677..013b0cd1958e 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -1935,7 +1935,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, + dst_reg->umax_value = umax_ptr; + dst_reg->var_off = ptr_reg->var_off; + dst_reg->off = ptr_reg->off + smin_val; +- dst_reg->range = ptr_reg->range; ++ dst_reg->raw = ptr_reg->raw; + break; + } + /* A new variable offset is created. Note that off_reg->off +@@ -1965,10 +1965,11 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, + } + dst_reg->var_off = tnum_add(ptr_reg->var_off, off_reg->var_off); + dst_reg->off = ptr_reg->off; ++ dst_reg->raw = ptr_reg->raw; + if (ptr_reg->type == PTR_TO_PACKET) { + dst_reg->id = ++env->id_gen; + /* something was added to pkt_ptr, set range to zero */ +- dst_reg->range = 0; ++ dst_reg->raw = 0; + } + break; + case BPF_SUB: +@@ -1999,7 +2000,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, + dst_reg->var_off = ptr_reg->var_off; + dst_reg->id = ptr_reg->id; + dst_reg->off = ptr_reg->off - smin_val; +- dst_reg->range = ptr_reg->range; ++ dst_reg->raw = ptr_reg->raw; + break; + } + /* A new variable offset is created. If the subtrahend is known +@@ -2025,11 +2026,12 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, + } + dst_reg->var_off = tnum_sub(ptr_reg->var_off, off_reg->var_off); + dst_reg->off = ptr_reg->off; ++ dst_reg->raw = ptr_reg->raw; + if (ptr_reg->type == PTR_TO_PACKET) { + dst_reg->id = ++env->id_gen; + /* something was added to pkt_ptr, set range to zero */ + if (smin_val < 0) +- dst_reg->range = 0; ++ dst_reg->raw = 0; + } + break; + case BPF_AND: +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index b2d699f28304..19bfa21f7197 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4299,9 +4299,13 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq) + + /* + * Add to the _head_ of the list, so that an already-started +- * distribute_cfs_runtime will not see us ++ * distribute_cfs_runtime will not see us. If disribute_cfs_runtime is ++ * not running add to the tail so that later runqueues don't get starved. + */ +- list_add_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq); ++ if (cfs_b->distribute_running) ++ list_add_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq); ++ else ++ list_add_tail_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq); + + /* + * If we're the first throttled task, make sure the bandwidth +@@ -4445,14 +4449,16 @@ static int do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b, int overrun) + * in us over-using our runtime if it is all used during this loop, but + * only by limited amounts in that extreme case. + */ +- while (throttled && cfs_b->runtime > 0) { ++ while (throttled && cfs_b->runtime > 0 && !cfs_b->distribute_running) { + runtime = cfs_b->runtime; ++ cfs_b->distribute_running = 1; + raw_spin_unlock(&cfs_b->lock); + /* we can't nest cfs_b->lock while distributing bandwidth */ + runtime = distribute_cfs_runtime(cfs_b, runtime, + runtime_expires); + raw_spin_lock(&cfs_b->lock); + ++ cfs_b->distribute_running = 0; + throttled = !list_empty(&cfs_b->throttled_cfs_rq); + + cfs_b->runtime -= min(runtime, cfs_b->runtime); +@@ -4563,6 +4569,11 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b) + + /* confirm we're still not at a refresh boundary */ + raw_spin_lock(&cfs_b->lock); ++ if (cfs_b->distribute_running) { ++ raw_spin_unlock(&cfs_b->lock); ++ return; ++ } ++ + if (runtime_refresh_within(cfs_b, min_bandwidth_expiration)) { + raw_spin_unlock(&cfs_b->lock); + return; +@@ -4572,6 +4583,9 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b) + runtime = cfs_b->runtime; + + expires = cfs_b->runtime_expires; ++ if (runtime) ++ cfs_b->distribute_running = 1; ++ + raw_spin_unlock(&cfs_b->lock); + + if (!runtime) +@@ -4582,6 +4596,7 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b) + raw_spin_lock(&cfs_b->lock); + if (expires == cfs_b->runtime_expires) + cfs_b->runtime -= min(runtime, cfs_b->runtime); ++ cfs_b->distribute_running = 0; + raw_spin_unlock(&cfs_b->lock); + } + +@@ -4690,6 +4705,7 @@ void init_cfs_bandwidth(struct cfs_bandwidth *cfs_b) + cfs_b->period_timer.function = sched_cfs_period_timer; + hrtimer_init(&cfs_b->slack_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + cfs_b->slack_timer.function = sched_cfs_slack_timer; ++ cfs_b->distribute_running = 0; + } + + static void init_cfs_rq_runtime(struct cfs_rq *cfs_rq) +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index b29376169f3f..63d999dfec80 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -288,6 +288,8 @@ struct cfs_bandwidth { + /* statistics */ + int nr_periods, nr_throttled; + u64 throttled_time; ++ ++ bool distribute_running; + #endif + }; + |