mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
This is the 4.14.80 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlvm/dUACgkQONu9yGCS aT6YIg//R0orm3h1s6oX17p8ttPz3SFmC36sOxMfWbmqqdPH2EE7bCHIrAkiKPt/ FTkeD1tSwzpepGrCj4ONG8Se+l2/DuRfMqrAeBmG8XVSyMoVciHdbSL6VUnJWODH lgmF58pp86a5hssiW2Syd6BZ/bqyubmPx/R7kwFKG76IuUvCBmUZcPSIHO1BtGyJ NJ5OlbnRJOrE+XOor9segukKhrynQCcQfT7HjOKm3T5PQEtCtsRekO1sPU+Gdhrq i2PZTOZdDr0YRFac+zqvI/6ufExNffXDYh56MpYyhiRLpDbCnbTxVKlNn5bKmTpA pPGyn6nSbaqU+BnPDFmApIoQY8UgjZf49n2HhVg4Or3+ArOflqY8z0Jlpu4o7YK7 l+4MUis0uBf67Mbvb8/zuk+N+e0/rFBfHvi1HJ+2Au7o+9Erp7YVLc2plwMUcIAX 6wZzH29Lcl5OrQBEZGmZJ1SWJ7jEHDZrmwRKM1vMqUqZMHG4cE5TLlEcAQTLSWng QsYF3/cdUzsCA3IeX1ArNIjXeWlitGhRv8tf1aiY238i8oaCKzfF7YbMrahMSk1H sk1KJzqEGwiLNHG+F7PHjLBmwxfVhQS90Y8kSLjz1MCqx0F3+S7TdZk9JfHI6l3h 7BUMsbc6f/M+IVmmQzlxdw+iMR0PjB+vq4b/pNPoowlXcLvM1qY= =Ns58 -----END PGP SIGNATURE----- Merge 4.14.80 into android-4.14 Changes in 4.14.80 eeprom: at24: Add support for address-width property vfs: swap names of {do,vfs}_clone_file_range() USB: serial: option: improve Quectel EP06 detection USB: serial: option: add two-endpoints device-id flag bpf: fix partial copy of map_ptr when dst is scalar Revert "ARM: tegra: Fix ULPI regression on Tegra20" fsnotify: fix ignore mask logic in fsnotify() gpio: mxs: Get rid of external API call xfs: truncate transaction does not modify the inobt cachefiles: fix the race between cachefiles_bury_object() and rmdir(2) ptp: fix Spectre v1 vulnerability drm/edid: Add 6 bpc quirk for BOE panel in HP Pavilion 15-n233sl drm/edid: VSDB yCBCr420 Deep Color mode bit definitions drm: fb-helper: Reject all pixel format changing requests RDMA/ucma: Fix Spectre v1 vulnerability IB/ucm: Fix Spectre v1 vulnerability cdc-acm: do not reset notification buffer index upon urb unlinking cdc-acm: correct counting of UART states in serial state notification cdc-acm: fix race between reset and control messaging usb: usbip: Fix BUG: KASAN: slab-out-of-bounds in vhci_hub_control() usb: gadget: storage: Fix Spectre v1 vulnerability USB: fix the usbfs flag sanitization for control transfers Input: elan_i2c - add ACPI ID for Lenovo IdeaPad 330-15IGM sched/fair: Fix throttle_list starvation with low CFS quota x86/tsc: Force inlining of cyc2ns bits x86, hibernate: Fix nosave_regions setup for hibernation x86/percpu: Fix this_cpu_read() x86/time: Correct the attribute on jiffies' definition x86/fpu: Fix i486 + no387 boot crash by only saving FPU registers on context switch if there is an FPU net: fs_enet: do not call phy_stop() in interrupts Linux 4.14.80 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
494c2659e6
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 14
|
||||
SUBLEVEL = 79
|
||||
SUBLEVEL = 80
|
||||
EXTRAVERSION =
|
||||
NAME = Petit Gorille
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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; \
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 },
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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]) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -1816,8 +1816,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);
|
||||
@ -1864,6 +1864,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);
|
||||
|
||||
/*
|
||||
|
@ -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))));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -1802,8 +1802,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);
|
||||
@ -2736,19 +2738,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.
|
||||
|
@ -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:
|
||||
|
@ -4567,9 +4567,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
|
||||
@ -4713,14 +4717,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);
|
||||
@ -4831,6 +4837,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;
|
||||
@ -4840,6 +4851,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)
|
||||
@ -4850,6 +4864,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);
|
||||
}
|
||||
|
||||
@ -4958,6 +4973,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)
|
||||
|
@ -288,6 +288,8 @@ struct cfs_bandwidth {
|
||||
/* statistics */
|
||||
int nr_periods, nr_throttled;
|
||||
u64 throttled_time;
|
||||
|
||||
bool distribute_running;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user