This is the 5.4.280 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmaY400ACgkQONu9yGCS aT4SOxAAsnnWA4GPcspY03fxcSwl+CdgDj22VVgxDW/va/rk7fcxo000snNgo2M+ K1x9qL3SPAXVEZNIUdSU001+/pnaaVdskXRNanwIvIuZMeh2cn8qmP+MFUPHLKWH aki1FPsh3lvI3x7JVioSWNvSuiaHgeXFBPKUB4wP5J51QYiuSWGb1gIrGCsCNiHI kboMmDEo1cxSLE+0wWzhBXn921FA1Vot10SqtYwQJnAICq2TsE2YPgshiMkrYZ4e 0KbTLizk390pDT+n+Nrnoi7wNoRX/KoHz7A/94l3zwp3/xv9glqeudt+Cy9esQjo yZQDkq6LtSW8ABWjcCXPMEg2r7p8HPmiOuCP8oHBo9kHNgyePbArEPWQP+xC3vzq zeMH09m+arw8njBYdKv3c+5VVY7ABHQK3Vfo2Z3MMf5ZZgTg7f+e7uBT4RcFBriq Eyne4CLPzuuzn/BEgcoPWxwaDs8mDThbxRlfSmnDbfE7IcuDGRH7EsvFuViSKE13 ncpLJu03bs/AhZe3eiLk+AWwb4gHJD1oBNWu1CkQ5XY2S0MxYxyYdlhNpGA5yvyO RqIhrTm+ye/NlD8X1jj2WAPTR3l94TTQoBsJAhsfceusC3OeS5537hKJNL4c8O1f GZM+vbAudy529iFVru84ZZLM31RwwOqRP3LRt1sOiSZs50FZ9HE= =Q9dw -----END PGP SIGNATURE----- Merge 5.4.280 into android11-5.4-lts Changes in 5.4.280 Compiler Attributes: Add __uninitialized macro drm/lima: fix shared irq handling on driver remove media: dvb: as102-fe: Fix as10x_register_addr packing media: dvb-usb: dib0700_devices: Add missing release_firmware() IB/core: Implement a limit on UMAD receive List scsi: qedf: Make qedf_execute_tmf() non-preemptible drm/amdgpu: Initialize timestamp for some legacy SOCs drm/amd/display: Skip finding free audio for unknown engine_id media: dw2102: Don't translate i2c read into write sctp: prefer struct_size over open coded arithmetic firmware: dmi: Stop decoding on broken entry Input: ff-core - prefer struct_size over open coded arithmetic net: dsa: mv88e6xxx: Correct check for empty list media: dvb-frontends: tda18271c2dd: Remove casting during div media: s2255: Use refcount_t instead of atomic_t for num_channels media: dvb-frontends: tda10048: Fix integer overflow i2c: i801: Annotate apanel_addr as __ro_after_init powerpc/64: Set _IO_BASE to POISON_POINTER_DELTA not 0 for CONFIG_PCI=n orangefs: fix out-of-bounds fsid access powerpc/xmon: Check cpu id in commands "c#", "dp#" and "dx#" jffs2: Fix potential illegal address access in jffs2_free_inode s390/pkey: Wipe sensitive data on failure tcp: tcp_mark_head_lost is only valid for sack-tcp tcp: add ece_ack flag to reno sack functions net: tcp better handling of reordering then loss cases UPSTREAM: tcp: fix DSACK undo in fast recovery to call tcp_try_to_open() tcp_metrics: validate source addr length wifi: wilc1000: fix ies_len type in connect path bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set() selftests: fix OOM in msg_zerocopy selftest selftests: make order checking verbose in msg_zerocopy selftest inet_diag: Initialize pad field in struct inet_diag_req_v2 nilfs2: fix inode number range checks nilfs2: add missing check for inode numbers on directory entries mm: optimize the redundant loop of mm_update_owner_next() can: kvaser_usb: Explicitly initialize family in leafimx driver_info struct fsnotify: Do not generate events for O_PATH file descriptors Revert "mm/writeback: fix possible divide-by-zero in wb_dirty_limits(), again" drm/nouveau: fix null pointer dereference in nouveau_connector_get_modes drm/amdgpu/atomfirmware: silence UBSAN warning bnx2x: Fix multiple UBSAN array-index-out-of-bounds media: dw2102: fix a potential buffer overflow i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897 nvme-multipath: find NUMA path only for online numa-node nilfs2: fix incorrect inode allocation from reserved inodes filelock: fix potential use-after-free in posix_lock_inode fs/dcache: Re-use value stored to dentry->d_flags instead of re-reading vfs: don't mod negative dentry count when on shrinker list tcp: add TCP_INFO status for failed client TFO tcp: fix incorrect undo caused by DSACK of TLP retransmit octeontx2-af: Fix incorrect value output on error path in rvu_check_rsrc_availability() net: lantiq_etop: add blank line after declaration net: ethernet: lantiq_etop: fix double free in detach ppp: reject claimed-as-LCP but actually malformed packets udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port(). s390: Mark psw in __load_psw_mask() as __unitialized ARM: davinci: Convert comma to semicolon octeontx2-af: fix detection of IP layer USB: serial: option: add Telit generic core-dump composition USB: serial: option: add Telit FN912 rmnet compositions USB: serial: option: add Fibocom FM350-GL USB: serial: option: add support for Foxconn T99W651 USB: serial: option: add Netprisma LCUK54 series modules USB: serial: option: add Rolling RW350-GL variants USB: Add USB_QUIRK_NO_SET_INTF quirk for START BP-850k usb: gadget: configfs: Prevent OOB read/write in usb_string_copy() USB: core: Fix duplicate endpoint bug by clearing reserved bits in the descriptor hpet: Support 32-bit userspace nvmem: meson-efuse: Fix return value of nvmem callbacks ALSA: hda/realtek: Limit mic boost on VAIO PRO PX libceph: fix race between delayed_work() and ceph_monc_stop() SUNRPC: Fix RPC client cleaned up the freed pipefs dentries tcp: refactor tcp_retransmit_timer() net: tcp: fix unexcepted socket die when snd_wnd is 0 tcp: use signed arithmetic in tcp_rtx_probe0_timed_out() tcp: avoid too many retransmit packets nilfs2: fix kernel bug on rename operation of broken directory i2c: rcar: bring hardware to known state when probing Linux 5.4.280 Change-Id: Ic487769acece8eedb10cc2a310d97f453abba2f0 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
f90cc3d8c1
73 changed files with 601 additions and 251 deletions
2
Makefile
2
Makefile
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 279
|
||||
SUBLEVEL = 280
|
||||
EXTRAVERSION =
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ static void davinci_pm_suspend(void)
|
|||
|
||||
/* Configure sleep count in deep sleep register */
|
||||
val = __raw_readl(pm_config.deepsleep_reg);
|
||||
val &= ~DEEPSLEEP_SLEEPCOUNT_MASK,
|
||||
val &= ~DEEPSLEEP_SLEEPCOUNT_MASK;
|
||||
val |= pm_config.sleepcount;
|
||||
__raw_writel(val, pm_config.deepsleep_reg);
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ extern struct pci_dev *isa_bridge_pcidev;
|
|||
* define properly based on the platform
|
||||
*/
|
||||
#ifndef CONFIG_PCI
|
||||
#define _IO_BASE 0
|
||||
#define _IO_BASE POISON_POINTER_DELTA
|
||||
#define _ISA_MEM_BASE 0
|
||||
#define PCI_DRAM_OFFSET 0
|
||||
#elif defined(CONFIG_PPC32)
|
||||
|
|
|
|||
|
|
@ -1214,7 +1214,7 @@ static int cpu_cmd(void)
|
|||
unsigned long cpu, first_cpu, last_cpu;
|
||||
int timeout;
|
||||
|
||||
if (!scanhex(&cpu)) {
|
||||
if (!scanhex(&cpu) || cpu >= num_possible_cpus()) {
|
||||
/* print cpus waiting or in xmon */
|
||||
printf("cpus stopped:");
|
||||
last_cpu = first_cpu = NR_CPUS;
|
||||
|
|
@ -2571,7 +2571,7 @@ static void dump_pacas(void)
|
|||
|
||||
termch = c; /* Put c back, it wasn't 'a' */
|
||||
|
||||
if (scanhex(&num))
|
||||
if (scanhex(&num) && num < num_possible_cpus())
|
||||
dump_one_paca(num);
|
||||
else
|
||||
dump_one_paca(xmon_owner);
|
||||
|
|
@ -2668,7 +2668,7 @@ static void dump_xives(void)
|
|||
|
||||
termch = c; /* Put c back, it wasn't 'a' */
|
||||
|
||||
if (scanhex(&num))
|
||||
if (scanhex(&num) && num < num_possible_cpus())
|
||||
dump_one_xive(num);
|
||||
else
|
||||
dump_one_xive(xmon_owner);
|
||||
|
|
|
|||
|
|
@ -256,8 +256,8 @@ static inline void __load_psw(psw_t psw)
|
|||
*/
|
||||
static __always_inline void __load_psw_mask(unsigned long mask)
|
||||
{
|
||||
psw_t psw __uninitialized;
|
||||
unsigned long addr;
|
||||
psw_t psw;
|
||||
|
||||
psw.mask = mask;
|
||||
|
||||
|
|
|
|||
|
|
@ -304,8 +304,13 @@ hpet_read(struct file *file, char __user *buf, size_t count, loff_t * ppos)
|
|||
if (!devp->hd_ireqfreq)
|
||||
return -EIO;
|
||||
|
||||
if (count < sizeof(unsigned long))
|
||||
return -EINVAL;
|
||||
if (in_compat_syscall()) {
|
||||
if (count < sizeof(compat_ulong_t))
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (count < sizeof(unsigned long))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
add_wait_queue(&devp->hd_waitqueue, &wait);
|
||||
|
||||
|
|
@ -329,9 +334,16 @@ hpet_read(struct file *file, char __user *buf, size_t count, loff_t * ppos)
|
|||
schedule();
|
||||
}
|
||||
|
||||
retval = put_user(data, (unsigned long __user *)buf);
|
||||
if (!retval)
|
||||
retval = sizeof(unsigned long);
|
||||
if (in_compat_syscall()) {
|
||||
retval = put_user(data, (compat_ulong_t __user *)buf);
|
||||
if (!retval)
|
||||
retval = sizeof(compat_ulong_t);
|
||||
} else {
|
||||
retval = put_user(data, (unsigned long __user *)buf);
|
||||
if (!retval)
|
||||
retval = sizeof(unsigned long);
|
||||
}
|
||||
|
||||
out:
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&devp->hd_waitqueue, &wait);
|
||||
|
|
@ -686,12 +698,24 @@ struct compat_hpet_info {
|
|||
unsigned short hi_timer;
|
||||
};
|
||||
|
||||
/* 32-bit types would lead to different command codes which should be
|
||||
* translated into 64-bit ones before passed to hpet_ioctl_common
|
||||
*/
|
||||
#define COMPAT_HPET_INFO _IOR('h', 0x03, struct compat_hpet_info)
|
||||
#define COMPAT_HPET_IRQFREQ _IOW('h', 0x6, compat_ulong_t)
|
||||
|
||||
static long
|
||||
hpet_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct hpet_info info;
|
||||
int err;
|
||||
|
||||
if (cmd == COMPAT_HPET_INFO)
|
||||
cmd = HPET_INFO;
|
||||
|
||||
if (cmd == COMPAT_HPET_IRQFREQ)
|
||||
cmd = HPET_IRQFREQ;
|
||||
|
||||
mutex_lock(&hpet_mutex);
|
||||
err = hpet_ioctl_common(file->private_data, cmd, arg, &info);
|
||||
mutex_unlock(&hpet_mutex);
|
||||
|
|
|
|||
|
|
@ -96,6 +96,17 @@ static void dmi_decode_table(u8 *buf,
|
|||
(data - buf + sizeof(struct dmi_header)) <= dmi_len) {
|
||||
const struct dmi_header *dm = (const struct dmi_header *)data;
|
||||
|
||||
/*
|
||||
* If a short entry is found (less than 4 bytes), not only it
|
||||
* is invalid, but we cannot reliably locate the next entry.
|
||||
*/
|
||||
if (dm->length < sizeof(struct dmi_header)) {
|
||||
pr_warn(FW_BUG
|
||||
"Corrupted DMI table, offset %zd (only %d entries processed)\n",
|
||||
data - buf, i);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We want to know the total length (formatted area and
|
||||
* strings) before decoding to make sure we won't run off the
|
||||
|
|
|
|||
|
|
@ -384,6 +384,14 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
|
|||
int r;
|
||||
|
||||
entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
|
||||
|
||||
/*
|
||||
* timestamp is not supported on some legacy SOCs (cik, cz, iceland,
|
||||
* si and tonga), so initialize timestamp and timestamp_src to 0
|
||||
*/
|
||||
entry.timestamp = 0;
|
||||
entry.timestamp_src = 0;
|
||||
|
||||
amdgpu_ih_decode_iv(adev, &entry);
|
||||
|
||||
trace_amdgpu_iv(ih - &adev->irq.ih, &entry);
|
||||
|
|
|
|||
|
|
@ -1646,6 +1646,9 @@ static struct audio *find_first_free_audio(
|
|||
{
|
||||
int i, available_audio_count;
|
||||
|
||||
if (id == ENGINE_ID_UNKNOWN)
|
||||
return NULL;
|
||||
|
||||
available_audio_count = pool->audio_count;
|
||||
|
||||
for (i = 0; i < available_audio_count; i++) {
|
||||
|
|
|
|||
|
|
@ -653,7 +653,7 @@ struct atom_gpio_pin_lut_v2_1
|
|||
{
|
||||
struct atom_common_table_header table_header;
|
||||
/*the real number of this included in the structure is calcualted by using the (whole structure size - the header size)/size of atom_gpio_pin_lut */
|
||||
struct atom_gpio_pin_assignment gpio_pin[8];
|
||||
struct atom_gpio_pin_assignment gpio_pin[];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -244,7 +244,9 @@ int lima_gp_init(struct lima_ip *ip)
|
|||
|
||||
void lima_gp_fini(struct lima_ip *ip)
|
||||
{
|
||||
struct lima_device *dev = ip->dev;
|
||||
|
||||
devm_free_irq(dev->dev, ip->irq, ip);
|
||||
}
|
||||
|
||||
int lima_gp_pipe_init(struct lima_device *dev)
|
||||
|
|
|
|||
|
|
@ -97,7 +97,12 @@ int lima_mmu_init(struct lima_ip *ip)
|
|||
|
||||
void lima_mmu_fini(struct lima_ip *ip)
|
||||
{
|
||||
struct lima_device *dev = ip->dev;
|
||||
|
||||
if (ip->id == lima_ip_ppmmu_bcast)
|
||||
return;
|
||||
|
||||
devm_free_irq(dev->dev, ip->irq, ip);
|
||||
}
|
||||
|
||||
void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm)
|
||||
|
|
|
|||
|
|
@ -251,7 +251,9 @@ int lima_pp_init(struct lima_ip *ip)
|
|||
|
||||
void lima_pp_fini(struct lima_ip *ip)
|
||||
{
|
||||
struct lima_device *dev = ip->dev;
|
||||
|
||||
devm_free_irq(dev->dev, ip->irq, ip);
|
||||
}
|
||||
|
||||
int lima_pp_bcast_init(struct lima_ip *ip)
|
||||
|
|
@ -272,7 +274,9 @@ int lima_pp_bcast_init(struct lima_ip *ip)
|
|||
|
||||
void lima_pp_bcast_fini(struct lima_ip *ip)
|
||||
{
|
||||
struct lima_device *dev = ip->dev;
|
||||
|
||||
devm_free_irq(dev->dev, ip->irq, ip);
|
||||
}
|
||||
|
||||
static int lima_pp_task_validate(struct lima_sched_pipe *pipe,
|
||||
|
|
|
|||
|
|
@ -968,6 +968,9 @@ nouveau_connector_get_modes(struct drm_connector *connector)
|
|||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(dev, nv_connector->native_mode);
|
||||
if (!mode)
|
||||
return 0;
|
||||
|
||||
drm_mode_probed_add(connector, mode);
|
||||
ret = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1057,7 +1057,7 @@ static const struct pci_device_id i801_ids[] = {
|
|||
MODULE_DEVICE_TABLE(pci, i801_ids);
|
||||
|
||||
#if defined CONFIG_X86 && defined CONFIG_DMI
|
||||
static unsigned char apanel_addr;
|
||||
static unsigned char apanel_addr __ro_after_init;
|
||||
|
||||
/* Scan the system ROM for the signature "FJKEYINF" */
|
||||
static __init const void __iomem *bios_signature(const void __iomem *bios)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
#include <linux/ioport.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
|
|
@ -32,7 +31,6 @@ struct i2c_pnx_mif {
|
|||
int ret; /* Return value */
|
||||
int mode; /* Interface mode */
|
||||
struct completion complete; /* I/O completion */
|
||||
struct timer_list timer; /* Timeout */
|
||||
u8 * buf; /* Data buffer */
|
||||
int len; /* Length of data buffer */
|
||||
int order; /* RX Bytes to order via TX */
|
||||
|
|
@ -117,24 +115,6 @@ static inline int wait_reset(struct i2c_pnx_algo_data *data)
|
|||
return (timeout <= 0);
|
||||
}
|
||||
|
||||
static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)
|
||||
{
|
||||
struct timer_list *timer = &alg_data->mif.timer;
|
||||
unsigned long expires = msecs_to_jiffies(alg_data->timeout);
|
||||
|
||||
if (expires <= 1)
|
||||
expires = 2;
|
||||
|
||||
del_timer_sync(timer);
|
||||
|
||||
dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",
|
||||
jiffies, expires);
|
||||
|
||||
timer->expires = jiffies + expires;
|
||||
|
||||
add_timer(timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* i2c_pnx_start - start a device
|
||||
* @slave_addr: slave address
|
||||
|
|
@ -259,8 +239,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
|
|||
~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
|
||||
I2C_REG_CTL(alg_data));
|
||||
|
||||
del_timer_sync(&alg_data->mif.timer);
|
||||
|
||||
dev_dbg(&alg_data->adapter.dev,
|
||||
"%s(): Waking up xfer routine.\n",
|
||||
__func__);
|
||||
|
|
@ -276,8 +254,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
|
|||
~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
|
||||
I2C_REG_CTL(alg_data));
|
||||
|
||||
/* Stop timer. */
|
||||
del_timer_sync(&alg_data->mif.timer);
|
||||
dev_dbg(&alg_data->adapter.dev,
|
||||
"%s(): Waking up xfer routine after zero-xfer.\n",
|
||||
__func__);
|
||||
|
|
@ -364,8 +340,6 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
|
|||
mcntrl_drmie | mcntrl_daie);
|
||||
iowrite32(ctl, I2C_REG_CTL(alg_data));
|
||||
|
||||
/* Kill timer. */
|
||||
del_timer_sync(&alg_data->mif.timer);
|
||||
complete(&alg_data->mif.complete);
|
||||
}
|
||||
}
|
||||
|
|
@ -400,8 +374,6 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
|
|||
mcntrl_drmie);
|
||||
iowrite32(ctl, I2C_REG_CTL(alg_data));
|
||||
|
||||
/* Stop timer, to prevent timeout. */
|
||||
del_timer_sync(&alg_data->mif.timer);
|
||||
complete(&alg_data->mif.complete);
|
||||
} else if (stat & mstatus_nai) {
|
||||
/* Slave did not acknowledge, generate a STOP */
|
||||
|
|
@ -419,8 +391,6 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
|
|||
/* Our return value. */
|
||||
alg_data->mif.ret = -EIO;
|
||||
|
||||
/* Stop timer, to prevent timeout. */
|
||||
del_timer_sync(&alg_data->mif.timer);
|
||||
complete(&alg_data->mif.complete);
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -453,9 +423,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void i2c_pnx_timeout(struct timer_list *t)
|
||||
static void i2c_pnx_timeout(struct i2c_pnx_algo_data *alg_data)
|
||||
{
|
||||
struct i2c_pnx_algo_data *alg_data = from_timer(alg_data, t, mif.timer);
|
||||
u32 ctl;
|
||||
|
||||
dev_err(&alg_data->adapter.dev,
|
||||
|
|
@ -472,7 +441,6 @@ static void i2c_pnx_timeout(struct timer_list *t)
|
|||
iowrite32(ctl, I2C_REG_CTL(alg_data));
|
||||
wait_reset(alg_data);
|
||||
alg_data->mif.ret = -EIO;
|
||||
complete(&alg_data->mif.complete);
|
||||
}
|
||||
|
||||
static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
|
||||
|
|
@ -514,6 +482,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
|||
struct i2c_msg *pmsg;
|
||||
int rc = 0, completed = 0, i;
|
||||
struct i2c_pnx_algo_data *alg_data = adap->algo_data;
|
||||
unsigned long time_left;
|
||||
u32 stat;
|
||||
|
||||
dev_dbg(&alg_data->adapter.dev,
|
||||
|
|
@ -548,7 +517,6 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
|||
dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
|
||||
__func__, alg_data->mif.mode, alg_data->mif.len);
|
||||
|
||||
i2c_pnx_arm_timer(alg_data);
|
||||
|
||||
/* initialize the completion var */
|
||||
init_completion(&alg_data->mif.complete);
|
||||
|
|
@ -564,7 +532,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
|||
break;
|
||||
|
||||
/* Wait for completion */
|
||||
wait_for_completion(&alg_data->mif.complete);
|
||||
time_left = wait_for_completion_timeout(&alg_data->mif.complete,
|
||||
alg_data->timeout);
|
||||
if (time_left == 0)
|
||||
i2c_pnx_timeout(alg_data);
|
||||
|
||||
if (!(rc = alg_data->mif.ret))
|
||||
completed++;
|
||||
|
|
@ -657,7 +628,10 @@ static int i2c_pnx_probe(struct platform_device *pdev)
|
|||
alg_data->adapter.algo_data = alg_data;
|
||||
alg_data->adapter.nr = pdev->id;
|
||||
|
||||
alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT;
|
||||
alg_data->timeout = msecs_to_jiffies(I2C_PNX_TIMEOUT_DEFAULT);
|
||||
if (alg_data->timeout <= 1)
|
||||
alg_data->timeout = 2;
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node);
|
||||
if (pdev->dev.of_node) {
|
||||
|
|
@ -677,8 +651,6 @@ static int i2c_pnx_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(alg_data->clk))
|
||||
return PTR_ERR(alg_data->clk);
|
||||
|
||||
timer_setup(&alg_data->mif.timer, i2c_pnx_timeout, 0);
|
||||
|
||||
snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name),
|
||||
"%s", pdev->name);
|
||||
|
||||
|
|
|
|||
|
|
@ -218,6 +218,14 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv)
|
|||
|
||||
}
|
||||
|
||||
static void rcar_i2c_reset_slave(struct rcar_i2c_priv *priv)
|
||||
{
|
||||
rcar_i2c_write(priv, ICSIER, 0);
|
||||
rcar_i2c_write(priv, ICSSR, 0);
|
||||
rcar_i2c_write(priv, ICSCR, SDBS);
|
||||
rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
|
||||
}
|
||||
|
||||
static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -863,11 +871,8 @@ static int rcar_unreg_slave(struct i2c_client *slave)
|
|||
|
||||
/* ensure no irq is running before clearing ptr */
|
||||
disable_irq(priv->irq);
|
||||
rcar_i2c_write(priv, ICSIER, 0);
|
||||
rcar_i2c_write(priv, ICSSR, 0);
|
||||
rcar_i2c_reset_slave(priv);
|
||||
enable_irq(priv->irq);
|
||||
rcar_i2c_write(priv, ICSCR, SDBS);
|
||||
rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
|
||||
|
||||
priv->slave = NULL;
|
||||
|
||||
|
|
@ -973,7 +978,9 @@ static int rcar_i2c_probe(struct platform_device *pdev)
|
|||
if (ret < 0)
|
||||
goto out_pm_put;
|
||||
|
||||
rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
|
||||
/* Bring hardware to known state */
|
||||
rcar_i2c_init(priv);
|
||||
rcar_i2c_reset_slave(priv);
|
||||
|
||||
if (priv->devtype == I2C_RCAR_GEN3) {
|
||||
priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ MODULE_AUTHOR("Roland Dreier");
|
|||
MODULE_DESCRIPTION("InfiniBand userspace MAD packet access");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
#define MAX_UMAD_RECV_LIST_SIZE 200000
|
||||
|
||||
enum {
|
||||
IB_UMAD_MAX_PORTS = RDMA_MAX_PORTS,
|
||||
IB_UMAD_MAX_AGENTS = 32,
|
||||
|
|
@ -113,6 +115,7 @@ struct ib_umad_file {
|
|||
struct mutex mutex;
|
||||
struct ib_umad_port *port;
|
||||
struct list_head recv_list;
|
||||
atomic_t recv_list_size;
|
||||
struct list_head send_list;
|
||||
struct list_head port_list;
|
||||
spinlock_t send_lock;
|
||||
|
|
@ -180,24 +183,28 @@ static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id)
|
|||
return file->agents_dead ? NULL : file->agent[id];
|
||||
}
|
||||
|
||||
static int queue_packet(struct ib_umad_file *file,
|
||||
struct ib_mad_agent *agent,
|
||||
struct ib_umad_packet *packet)
|
||||
static int queue_packet(struct ib_umad_file *file, struct ib_mad_agent *agent,
|
||||
struct ib_umad_packet *packet, bool is_recv_mad)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
mutex_lock(&file->mutex);
|
||||
|
||||
if (is_recv_mad &&
|
||||
atomic_read(&file->recv_list_size) > MAX_UMAD_RECV_LIST_SIZE)
|
||||
goto unlock;
|
||||
|
||||
for (packet->mad.hdr.id = 0;
|
||||
packet->mad.hdr.id < IB_UMAD_MAX_AGENTS;
|
||||
packet->mad.hdr.id++)
|
||||
if (agent == __get_agent(file, packet->mad.hdr.id)) {
|
||||
list_add_tail(&packet->list, &file->recv_list);
|
||||
atomic_inc(&file->recv_list_size);
|
||||
wake_up_interruptible(&file->recv_wait);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&file->mutex);
|
||||
|
||||
return ret;
|
||||
|
|
@ -224,7 +231,7 @@ static void send_handler(struct ib_mad_agent *agent,
|
|||
if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
|
||||
packet->length = IB_MGMT_MAD_HDR;
|
||||
packet->mad.hdr.status = ETIMEDOUT;
|
||||
if (!queue_packet(file, agent, packet))
|
||||
if (!queue_packet(file, agent, packet, false))
|
||||
return;
|
||||
}
|
||||
kfree(packet);
|
||||
|
|
@ -284,7 +291,7 @@ static void recv_handler(struct ib_mad_agent *agent,
|
|||
rdma_destroy_ah_attr(&ah_attr);
|
||||
}
|
||||
|
||||
if (queue_packet(file, agent, packet))
|
||||
if (queue_packet(file, agent, packet, true))
|
||||
goto err2;
|
||||
return;
|
||||
|
||||
|
|
@ -409,6 +416,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf,
|
|||
|
||||
packet = list_entry(file->recv_list.next, struct ib_umad_packet, list);
|
||||
list_del(&packet->list);
|
||||
atomic_dec(&file->recv_list_size);
|
||||
|
||||
mutex_unlock(&file->mutex);
|
||||
|
||||
|
|
@ -421,6 +429,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf,
|
|||
/* Requeue packet */
|
||||
mutex_lock(&file->mutex);
|
||||
list_add(&packet->list, &file->recv_list);
|
||||
atomic_inc(&file->recv_list_size);
|
||||
mutex_unlock(&file->mutex);
|
||||
} else {
|
||||
if (packet->recv_wc)
|
||||
|
|
|
|||
|
|
@ -12,8 +12,10 @@
|
|||
/* #define DEBUG */
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
|
@ -318,9 +320,8 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ff_dev_size = sizeof(struct ff_device) +
|
||||
max_effects * sizeof(struct file *);
|
||||
if (ff_dev_size < max_effects) /* overflow */
|
||||
ff_dev_size = struct_size(ff, effect_owners, max_effects);
|
||||
if (ff_dev_size == SIZE_MAX) /* overflow */
|
||||
return -EINVAL;
|
||||
|
||||
ff = kzalloc(ff_dev_size, GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -174,6 +174,6 @@ struct as10x_register_addr {
|
|||
uint32_t addr;
|
||||
/* register mode access */
|
||||
uint8_t mode;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -410,6 +410,7 @@ static int tda10048_set_if(struct dvb_frontend *fe, u32 bw)
|
|||
struct tda10048_config *config = &state->config;
|
||||
int i;
|
||||
u32 if_freq_khz;
|
||||
u64 sample_freq;
|
||||
|
||||
dprintk(1, "%s(bw = %d)\n", __func__, bw);
|
||||
|
||||
|
|
@ -451,9 +452,11 @@ static int tda10048_set_if(struct dvb_frontend *fe, u32 bw)
|
|||
dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor);
|
||||
|
||||
/* Calculate the sample frequency */
|
||||
state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45);
|
||||
state->sample_freq /= (state->pll_nfactor + 1);
|
||||
state->sample_freq /= (state->pll_pfactor + 4);
|
||||
sample_freq = state->xtal_hz;
|
||||
sample_freq *= state->pll_mfactor + 45;
|
||||
do_div(sample_freq, state->pll_nfactor + 1);
|
||||
do_div(sample_freq, state->pll_pfactor + 4);
|
||||
state->sample_freq = sample_freq;
|
||||
dprintk(1, "- sample_freq = %d\n", state->sample_freq);
|
||||
|
||||
/* Update the I/F */
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ static int CalcMainPLL(struct tda_state *state, u32 freq)
|
|||
|
||||
OscFreq = (u64) freq * (u64) Div;
|
||||
OscFreq *= (u64) 16384;
|
||||
do_div(OscFreq, (u64)16000000);
|
||||
do_div(OscFreq, 16000000);
|
||||
MainDiv = OscFreq;
|
||||
|
||||
state->m_Regs[MPD] = PostDiv & 0x77;
|
||||
|
|
@ -355,7 +355,7 @@ static int CalcCalPLL(struct tda_state *state, u32 freq)
|
|||
OscFreq = (u64)freq * (u64)Div;
|
||||
/* CalDiv = u32( OscFreq * 16384 / 16000000 ); */
|
||||
OscFreq *= (u64)16384;
|
||||
do_div(OscFreq, (u64)16000000);
|
||||
do_div(OscFreq, 16000000);
|
||||
CalDiv = OscFreq;
|
||||
|
||||
state->m_Regs[CPD] = PostDiv;
|
||||
|
|
|
|||
|
|
@ -2424,7 +2424,12 @@ static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap)
|
|||
|
||||
adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
|
||||
|
||||
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
|
||||
if (!adap->fe_adap[0].fe) {
|
||||
release_firmware(state->frontend_firmware);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dib9090_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
|
|
@ -2497,8 +2502,10 @@ static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap)
|
|||
dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80);
|
||||
adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
|
||||
|
||||
if (adap->fe_adap[0].fe == NULL)
|
||||
if (!adap->fe_adap[0].fe) {
|
||||
release_firmware(state->frontend_firmware);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0);
|
||||
dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82);
|
||||
|
|
@ -2506,7 +2513,12 @@ static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap)
|
|||
fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]);
|
||||
dib9000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
|
||||
|
||||
return fe_slave == NULL ? -ENODEV : 0;
|
||||
if (!fe_slave) {
|
||||
release_firmware(state->frontend_firmware);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
|
|
|
|||
|
|
@ -716,6 +716,7 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
struct dw2102_state *state;
|
||||
int j;
|
||||
|
||||
if (!d)
|
||||
return -ENODEV;
|
||||
|
|
@ -729,11 +730,11 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
return -EAGAIN;
|
||||
}
|
||||
|
||||
switch (num) {
|
||||
case 1:
|
||||
switch (msg[0].addr) {
|
||||
j = 0;
|
||||
while (j < num) {
|
||||
switch (msg[j].addr) {
|
||||
case SU3000_STREAM_CTRL:
|
||||
state->data[0] = msg[0].buf[0] + 0x36;
|
||||
state->data[0] = msg[j].buf[0] + 0x36;
|
||||
state->data[1] = 3;
|
||||
state->data[2] = 0;
|
||||
if (dvb_usb_generic_rw(d, state->data, 3,
|
||||
|
|
@ -745,61 +746,86 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
if (dvb_usb_generic_rw(d, state->data, 1,
|
||||
state->data, 2, 0) < 0)
|
||||
err("i2c transfer failed.");
|
||||
msg[0].buf[1] = state->data[0];
|
||||
msg[0].buf[0] = state->data[1];
|
||||
msg[j].buf[1] = state->data[0];
|
||||
msg[j].buf[0] = state->data[1];
|
||||
break;
|
||||
default:
|
||||
if (3 + msg[0].len > sizeof(state->data)) {
|
||||
warn("i2c wr: len=%d is too big!\n",
|
||||
msg[0].len);
|
||||
/* if the current write msg is followed by a another
|
||||
* read msg to/from the same address
|
||||
*/
|
||||
if ((j+1 < num) && (msg[j+1].flags & I2C_M_RD) &&
|
||||
(msg[j].addr == msg[j+1].addr)) {
|
||||
/* join both i2c msgs to one usb read command */
|
||||
if (4 + msg[j].len > sizeof(state->data)) {
|
||||
warn("i2c combined wr/rd: write len=%d is too big!\n",
|
||||
msg[j].len);
|
||||
num = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
if (1 + msg[j+1].len > sizeof(state->data)) {
|
||||
warn("i2c combined wr/rd: read len=%d is too big!\n",
|
||||
msg[j+1].len);
|
||||
num = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
state->data[0] = 0x09;
|
||||
state->data[1] = msg[j].len;
|
||||
state->data[2] = msg[j+1].len;
|
||||
state->data[3] = msg[j].addr;
|
||||
memcpy(&state->data[4], msg[j].buf, msg[j].len);
|
||||
|
||||
if (dvb_usb_generic_rw(d, state->data, msg[j].len + 4,
|
||||
state->data, msg[j+1].len + 1, 0) < 0)
|
||||
err("i2c transfer failed.");
|
||||
|
||||
memcpy(msg[j+1].buf, &state->data[1], msg[j+1].len);
|
||||
j++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (msg[j].flags & I2C_M_RD) {
|
||||
/* single read */
|
||||
if (4 + msg[j].len > sizeof(state->data)) {
|
||||
warn("i2c rd: len=%d is too big!\n", msg[j].len);
|
||||
num = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
state->data[0] = 0x09;
|
||||
state->data[1] = 0;
|
||||
state->data[2] = msg[j].len;
|
||||
state->data[3] = msg[j].addr;
|
||||
memcpy(&state->data[4], msg[j].buf, msg[j].len);
|
||||
|
||||
if (dvb_usb_generic_rw(d, state->data, 4,
|
||||
state->data, msg[j].len + 1, 0) < 0)
|
||||
err("i2c transfer failed.");
|
||||
|
||||
memcpy(msg[j].buf, &state->data[1], msg[j].len);
|
||||
break;
|
||||
}
|
||||
|
||||
/* single write */
|
||||
if (3 + msg[j].len > sizeof(state->data)) {
|
||||
warn("i2c wr: len=%d is too big!\n", msg[j].len);
|
||||
num = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
/* always i2c write*/
|
||||
state->data[0] = 0x08;
|
||||
state->data[1] = msg[0].addr;
|
||||
state->data[2] = msg[0].len;
|
||||
state->data[1] = msg[j].addr;
|
||||
state->data[2] = msg[j].len;
|
||||
|
||||
memcpy(&state->data[3], msg[0].buf, msg[0].len);
|
||||
memcpy(&state->data[3], msg[j].buf, msg[j].len);
|
||||
|
||||
if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
|
||||
if (dvb_usb_generic_rw(d, state->data, msg[j].len + 3,
|
||||
state->data, 1, 0) < 0)
|
||||
err("i2c transfer failed.");
|
||||
} // switch
|
||||
j++;
|
||||
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* always i2c read */
|
||||
if (4 + msg[0].len > sizeof(state->data)) {
|
||||
warn("i2c rd: len=%d is too big!\n",
|
||||
msg[0].len);
|
||||
num = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
if (1 + msg[1].len > sizeof(state->data)) {
|
||||
warn("i2c rd: len=%d is too big!\n",
|
||||
msg[1].len);
|
||||
num = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
state->data[0] = 0x09;
|
||||
state->data[1] = msg[0].len;
|
||||
state->data[2] = msg[1].len;
|
||||
state->data[3] = msg[0].addr;
|
||||
memcpy(&state->data[4], msg[0].buf, msg[0].len);
|
||||
|
||||
if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
|
||||
state->data, msg[1].len + 1, 0) < 0)
|
||||
err("i2c transfer failed.");
|
||||
|
||||
memcpy(msg[1].buf, &state->data[1], msg[1].len);
|
||||
break;
|
||||
default:
|
||||
warn("more than 2 i2c messages at a time is not handled yet.");
|
||||
break;
|
||||
}
|
||||
} // while
|
||||
mutex_unlock(&d->data_mutex);
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
return num;
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ struct s2255_vc {
|
|||
struct s2255_dev {
|
||||
struct s2255_vc vc[MAX_CHANNELS];
|
||||
struct v4l2_device v4l2_dev;
|
||||
atomic_t num_channels;
|
||||
refcount_t num_channels;
|
||||
int frames;
|
||||
struct mutex lock; /* channels[].vdev.lock */
|
||||
struct mutex cmdlock; /* protects cmdbuf */
|
||||
|
|
@ -1552,11 +1552,11 @@ static void s2255_video_device_release(struct video_device *vdev)
|
|||
container_of(vdev, struct s2255_vc, vdev);
|
||||
|
||||
dprintk(dev, 4, "%s, chnls: %d\n", __func__,
|
||||
atomic_read(&dev->num_channels));
|
||||
refcount_read(&dev->num_channels));
|
||||
|
||||
v4l2_ctrl_handler_free(&vc->hdl);
|
||||
|
||||
if (atomic_dec_and_test(&dev->num_channels))
|
||||
if (refcount_dec_and_test(&dev->num_channels))
|
||||
s2255_destroy(dev);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1661,7 +1661,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
|
|||
"failed to register video device!\n");
|
||||
break;
|
||||
}
|
||||
atomic_inc(&dev->num_channels);
|
||||
refcount_inc(&dev->num_channels);
|
||||
v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
|
||||
video_device_node_name(&vc->vdev));
|
||||
|
||||
|
|
@ -1669,11 +1669,11 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
|
|||
pr_info("Sensoray 2255 V4L driver Revision: %s\n",
|
||||
S2255_VERSION);
|
||||
/* if no channels registered, return error and probe will fail*/
|
||||
if (atomic_read(&dev->num_channels) == 0) {
|
||||
if (refcount_read(&dev->num_channels) == 0) {
|
||||
v4l2_device_unregister(&dev->v4l2_dev);
|
||||
return ret;
|
||||
}
|
||||
if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
|
||||
if (refcount_read(&dev->num_channels) != MAX_CHANNELS)
|
||||
pr_warn("s2255: Not all channels available.\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2222,7 +2222,7 @@ static int s2255_probe(struct usb_interface *interface,
|
|||
goto errorFWDATA1;
|
||||
}
|
||||
|
||||
atomic_set(&dev->num_channels, 0);
|
||||
refcount_set(&dev->num_channels, 0);
|
||||
dev->pid = id->idProduct;
|
||||
dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
|
||||
if (!dev->fw_data)
|
||||
|
|
@ -2342,12 +2342,12 @@ static void s2255_disconnect(struct usb_interface *interface)
|
|||
{
|
||||
struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
|
||||
int i;
|
||||
int channels = atomic_read(&dev->num_channels);
|
||||
int channels = refcount_read(&dev->num_channels);
|
||||
mutex_lock(&dev->lock);
|
||||
v4l2_device_disconnect(&dev->v4l2_dev);
|
||||
mutex_unlock(&dev->lock);
|
||||
/*see comments in the uvc_driver.c usb disconnect function */
|
||||
atomic_inc(&dev->num_channels);
|
||||
refcount_inc(&dev->num_channels);
|
||||
/* unregister each video device. */
|
||||
for (i = 0; i < channels; i++)
|
||||
video_unregister_device(&dev->vc[i].vdev);
|
||||
|
|
@ -2360,7 +2360,7 @@ static void s2255_disconnect(struct usb_interface *interface)
|
|||
dev->vc[i].vidstatus_ready = 1;
|
||||
wake_up(&dev->vc[i].wait_vidstatus);
|
||||
}
|
||||
if (atomic_dec_and_test(&dev->num_channels))
|
||||
if (refcount_dec_and_test(&dev->num_channels))
|
||||
s2255_destroy(dev);
|
||||
dev_info(&interface->dev, "%s\n", __func__);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1084,9 +1084,9 @@ static int bond_option_arp_ip_targets_set(struct bonding *bond,
|
|||
__be32 target;
|
||||
|
||||
if (newval->string) {
|
||||
if (!in4_pton(newval->string+1, -1, (u8 *)&target, -1, NULL)) {
|
||||
netdev_err(bond->dev, "invalid ARP target %pI4 specified\n",
|
||||
&target);
|
||||
if (strlen(newval->string) < 1 ||
|
||||
!in4_pton(newval->string + 1, -1, (u8 *)&target, -1, NULL)) {
|
||||
netdev_err(bond->dev, "invalid ARP target specified\n");
|
||||
return ret;
|
||||
}
|
||||
if (newval->string[0] == '+')
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_liste
|
|||
|
||||
static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = {
|
||||
.quirks = 0,
|
||||
.family = KVASER_LEAF,
|
||||
.ops = &kvaser_usb_leaf_dev_ops,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -115,8 +115,8 @@ struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
|
|||
{
|
||||
struct mv88e6xxx_mdio_bus *mdio_bus;
|
||||
|
||||
mdio_bus = list_first_entry(&chip->mdios, struct mv88e6xxx_mdio_bus,
|
||||
list);
|
||||
mdio_bus = list_first_entry_or_null(&chip->mdios,
|
||||
struct mv88e6xxx_mdio_bus, list);
|
||||
if (!mdio_bus)
|
||||
return NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -1256,7 +1256,7 @@ enum {
|
|||
|
||||
struct bnx2x_fw_stats_req {
|
||||
struct stats_query_header hdr;
|
||||
struct stats_query_entry query[FP_SB_MAX_E1x+
|
||||
struct stats_query_entry query[FP_SB_MAX_E2 +
|
||||
BNX2X_FIRST_QUEUE_QUERY_IDX];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -213,8 +213,9 @@ ltq_etop_free_channel(struct net_device *dev, struct ltq_etop_chan *ch)
|
|||
if (ch->dma.irq)
|
||||
free_irq(ch->dma.irq, priv);
|
||||
if (IS_RX(ch->idx)) {
|
||||
int desc;
|
||||
for (desc = 0; desc < LTQ_DESC_NUM; desc++)
|
||||
struct ltq_dma_channel *dma = &ch->dma;
|
||||
|
||||
for (dma->desc = 0; dma->desc < LTQ_DESC_NUM; dma->desc++)
|
||||
dev_kfree_skb_any(ch->skb[ch->dma.desc]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,14 +38,18 @@ enum npc_kpu_lb_ltype {
|
|||
NPC_LT_LB_ITAG,
|
||||
};
|
||||
|
||||
/* Don't modify ltypes up to IP6_EXT, otherwise length and checksum of IP
|
||||
* headers may not be checked correctly. IPv4 ltypes and IPv6 ltypes must
|
||||
* differ only at bit 0 so mask 0xE can be used to detect extended headers.
|
||||
*/
|
||||
enum npc_kpu_lc_ltype {
|
||||
NPC_LT_LC_IP = 1,
|
||||
NPC_LT_LC_PTP = 1,
|
||||
NPC_LT_LC_IP,
|
||||
NPC_LT_LC_IP6,
|
||||
NPC_LT_LC_ARP,
|
||||
NPC_LT_LC_RARP,
|
||||
NPC_LT_LC_MPLS,
|
||||
NPC_LT_LC_NSH,
|
||||
NPC_LT_LC_PTP,
|
||||
NPC_LT_LC_FCOE,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1124,7 +1124,7 @@ static int rvu_check_rsrc_availability(struct rvu *rvu,
|
|||
if (req->ssow > block->lf.max) {
|
||||
dev_err(&rvu->pdev->dev,
|
||||
"Func 0x%x: Invalid SSOW req, %d > max %d\n",
|
||||
pcifunc, req->sso, block->lf.max);
|
||||
pcifunc, req->ssow, block->lf.max);
|
||||
return -EINVAL;
|
||||
}
|
||||
mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->type);
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@
|
|||
#define MPHDRLEN_SSN 4 /* ditto with short sequence numbers */
|
||||
|
||||
#define PPP_PROTO_LEN 2
|
||||
#define PPP_LCP_HDRLEN 4
|
||||
|
||||
/*
|
||||
* An instance of /dev/ppp can be associated with either a ppp
|
||||
|
|
@ -491,6 +492,15 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool ppp_check_packet(struct sk_buff *skb, size_t count)
|
||||
{
|
||||
/* LCP packets must include LCP header which 4 bytes long:
|
||||
* 1-byte code, 1-byte identifier, and 2-byte length.
|
||||
*/
|
||||
return get_unaligned_be16(skb->data) != PPP_LCP ||
|
||||
count >= PPP_PROTO_LEN + PPP_LCP_HDRLEN;
|
||||
}
|
||||
|
||||
static ssize_t ppp_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
|
@ -513,6 +523,11 @@ static ssize_t ppp_write(struct file *file, const char __user *buf,
|
|||
kfree_skb(skb);
|
||||
goto out;
|
||||
}
|
||||
ret = -EINVAL;
|
||||
if (unlikely(!ppp_check_packet(skb, count))) {
|
||||
kfree_skb(skb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (pf->kind) {
|
||||
case INTERFACE:
|
||||
|
|
|
|||
|
|
@ -437,7 +437,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
|
|||
int node, srcu_idx;
|
||||
|
||||
srcu_idx = srcu_read_lock(&head->srcu);
|
||||
for_each_node(node)
|
||||
for_each_online_node(node)
|
||||
__nvme_find_path(head, node);
|
||||
srcu_read_unlock(&head->srcu, srcu_idx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,18 +18,24 @@ static int meson_efuse_read(void *context, unsigned int offset,
|
|||
void *val, size_t bytes)
|
||||
{
|
||||
struct meson_sm_firmware *fw = context;
|
||||
int ret;
|
||||
|
||||
return meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
|
||||
bytes, 0, 0, 0);
|
||||
ret = meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
|
||||
bytes, 0, 0, 0);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static int meson_efuse_write(void *context, unsigned int offset,
|
||||
void *val, size_t bytes)
|
||||
{
|
||||
struct meson_sm_firmware *fw = context;
|
||||
int ret;
|
||||
|
||||
return meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
|
||||
bytes, 0, 0, 0);
|
||||
ret = meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
|
||||
bytes, 0, 0, 0);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id meson_efuse_match[] = {
|
||||
|
|
|
|||
|
|
@ -784,7 +784,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
|
|||
if (rc)
|
||||
break;
|
||||
if (copy_to_user(ucs, &kcs, sizeof(kcs)))
|
||||
return -EFAULT;
|
||||
rc = -EFAULT;
|
||||
memzero_explicit(&kcs, sizeof(kcs));
|
||||
break;
|
||||
}
|
||||
|
|
@ -816,7 +816,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
|
|||
if (rc)
|
||||
break;
|
||||
if (copy_to_user(ucp, &kcp, sizeof(kcp)))
|
||||
return -EFAULT;
|
||||
rc = -EFAULT;
|
||||
memzero_explicit(&kcp, sizeof(kcp));
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2330,9 +2330,6 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd,
|
|||
io_req->fcport = fcport;
|
||||
io_req->cmd_type = QEDF_TASK_MGMT_CMD;
|
||||
|
||||
/* Record which cpu this request is associated with */
|
||||
io_req->cpu = smp_processor_id();
|
||||
|
||||
/* Set TM flags */
|
||||
io_req->io_req_flags = QEDF_READ;
|
||||
io_req->data_xfer_len = 0;
|
||||
|
|
@ -2354,6 +2351,9 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd,
|
|||
|
||||
spin_lock_irqsave(&fcport->rport_lock, flags);
|
||||
|
||||
/* Record which cpu this request is associated with */
|
||||
io_req->cpu = smp_processor_id();
|
||||
|
||||
sqe_idx = qedf_get_sqe_idx(fcport);
|
||||
sqe = &fcport->sq[sqe_idx];
|
||||
memset(sqe, 0, sizeof(struct fcoe_wqe));
|
||||
|
|
|
|||
|
|
@ -446,7 +446,8 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
|
|||
struct ieee80211_p2p_noa_attr noa_attr;
|
||||
const struct cfg80211_bss_ies *ies;
|
||||
struct wilc_join_bss_param *param;
|
||||
u8 rates_len = 0, ies_len;
|
||||
u8 rates_len = 0;
|
||||
int ies_len;
|
||||
int ret;
|
||||
|
||||
param = kzalloc(sizeof(*param), GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -291,6 +291,20 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
|
|||
if (ifp->desc.bNumEndpoints >= num_ep)
|
||||
goto skip_to_next_endpoint_or_interface_descriptor;
|
||||
|
||||
/* Save a copy of the descriptor and use it instead of the original */
|
||||
endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];
|
||||
memcpy(&endpoint->desc, d, n);
|
||||
d = &endpoint->desc;
|
||||
|
||||
/* Clear the reserved bits in bEndpointAddress */
|
||||
i = d->bEndpointAddress &
|
||||
(USB_ENDPOINT_DIR_MASK | USB_ENDPOINT_NUMBER_MASK);
|
||||
if (i != d->bEndpointAddress) {
|
||||
dev_notice(ddev, "config %d interface %d altsetting %d has an endpoint descriptor with address 0x%X, changing to 0x%X\n",
|
||||
cfgno, inum, asnum, d->bEndpointAddress, i);
|
||||
endpoint->desc.bEndpointAddress = i;
|
||||
}
|
||||
|
||||
/* Check for duplicate endpoint addresses */
|
||||
if (config_endpoint_is_duplicate(config, inum, asnum, d)) {
|
||||
dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n",
|
||||
|
|
@ -308,10 +322,8 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,
|
|||
}
|
||||
}
|
||||
|
||||
endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];
|
||||
/* Accept this endpoint */
|
||||
++ifp->desc.bNumEndpoints;
|
||||
|
||||
memcpy(&endpoint->desc, d, n);
|
||||
INIT_LIST_HEAD(&endpoint->urb_list);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -504,6 +504,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
{ USB_DEVICE(0x1b1c, 0x1b38), .driver_info = USB_QUIRK_DELAY_INIT |
|
||||
USB_QUIRK_DELAY_CTRL_MSG },
|
||||
|
||||
/* START BP-850k Printer */
|
||||
{ USB_DEVICE(0x1bc3, 0x0003), .driver_info = USB_QUIRK_NO_SET_INTF },
|
||||
|
||||
/* MIDI keyboard WORLDE MINI */
|
||||
{ USB_DEVICE(0x1c75, 0x0204), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
|
|
|||
|
|
@ -148,9 +148,12 @@ static int usb_string_copy(const char *s, char **s_copy)
|
|||
int ret;
|
||||
char *str;
|
||||
char *copy = *s_copy;
|
||||
|
||||
ret = strlen(s);
|
||||
if (ret > USB_MAX_STRING_LEN)
|
||||
return -EOVERFLOW;
|
||||
if (ret < 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy) {
|
||||
str = copy;
|
||||
|
|
|
|||
|
|
@ -1425,6 +1425,10 @@ static const struct usb_device_id option_ids[] = {
|
|||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff), /* Telit LN940 (MBIM) */
|
||||
.driver_info = NCTRL(0) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x3000, 0xff), /* Telit FN912 */
|
||||
.driver_info = RSVD(0) | NCTRL(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x3001, 0xff), /* Telit FN912 */
|
||||
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7010, 0xff), /* Telit LE910-S1 (RNDIS) */
|
||||
.driver_info = NCTRL(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7011, 0xff), /* Telit LE910-S1 (ECM) */
|
||||
|
|
@ -1433,6 +1437,8 @@ static const struct usb_device_id option_ids[] = {
|
|||
.driver_info = NCTRL(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701b, 0xff), /* Telit LE910R1 (ECM) */
|
||||
.driver_info = NCTRL(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x9000, 0xff), /* Telit generic core-dump device */
|
||||
.driver_info = NCTRL(0) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */
|
||||
.driver_info = NCTRL(0) | ZLP },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, 0x9200), /* Telit LE910S1 flashing device */
|
||||
|
|
@ -2224,6 +2230,10 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7106_2COM, 0x02, 0x02, 0x01) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x02, 0x01) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x00, 0x00) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x7126, 0xff, 0x00, 0x00),
|
||||
.driver_info = NCTRL(2) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x7127, 0xff, 0x00, 0x00),
|
||||
.driver_info = NCTRL(2) | NCTRL(3) | NCTRL(4) },
|
||||
{ USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
|
||||
{ USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MPL200),
|
||||
.driver_info = RSVD(1) | RSVD(4) },
|
||||
|
|
@ -2284,6 +2294,8 @@ static const struct usb_device_id option_ids[] = {
|
|||
.driver_info = RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0f0, 0xff), /* Foxconn T99W373 MBIM */
|
||||
.driver_info = RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe145, 0xff), /* Foxconn T99W651 RNDIS */
|
||||
.driver_info = RSVD(5) | RSVD(6) },
|
||||
{ USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */
|
||||
.driver_info = RSVD(4) | RSVD(5) | RSVD(6) },
|
||||
{ USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */
|
||||
|
|
@ -2321,6 +2333,32 @@ static const struct usb_device_id option_ids[] = {
|
|||
.driver_info = RSVD(4) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0115, 0xff), /* Rolling RW135-GL (laptop MBIM) */
|
||||
.driver_info = RSVD(5) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0802, 0xff), /* Rolling RW350-GL (laptop MBIM) */
|
||||
.driver_info = RSVD(5) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Global */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0x00, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0101, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WRD for Global SKU */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0101, 0xff, 0x00, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0101, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0106, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WRD for China SKU */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0106, 0xff, 0x00, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0106, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0111, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for SA */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0111, 0xff, 0x00, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0111, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0112, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for EU */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0112, 0xff, 0x00, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0112, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0113, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for NA */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0113, 0xff, 0x00, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0113, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0115, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for China EDU */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0115, 0xff, 0x00, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0115, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Golbal EDU */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0x00, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0116, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
|
||||
|
|
|
|||
12
fs/dcache.c
12
fs/dcache.c
|
|
@ -329,7 +329,11 @@ static inline void __d_clear_type_and_inode(struct dentry *dentry)
|
|||
flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU);
|
||||
WRITE_ONCE(dentry->d_flags, flags);
|
||||
dentry->d_inode = NULL;
|
||||
if (dentry->d_flags & DCACHE_LRU_LIST)
|
||||
/*
|
||||
* The negative counter only tracks dentries on the LRU. Don't inc if
|
||||
* d_lru is on another list.
|
||||
*/
|
||||
if ((flags & (DCACHE_LRU_LIST|DCACHE_SHRINK_LIST)) == DCACHE_LRU_LIST)
|
||||
this_cpu_inc(nr_dentry_negative);
|
||||
}
|
||||
|
||||
|
|
@ -1921,9 +1925,11 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
|
|||
|
||||
spin_lock(&dentry->d_lock);
|
||||
/*
|
||||
* Decrement negative dentry count if it was in the LRU list.
|
||||
* The negative counter only tracks dentries on the LRU. Don't dec if
|
||||
* d_lru is on another list.
|
||||
*/
|
||||
if (dentry->d_flags & DCACHE_LRU_LIST)
|
||||
if ((dentry->d_flags &
|
||||
(DCACHE_LRU_LIST|DCACHE_SHRINK_LIST)) == DCACHE_LRU_LIST)
|
||||
this_cpu_dec(nr_dentry_negative);
|
||||
hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
|
||||
raw_write_seqcount_begin(&dentry->d_seq);
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ static void jffs2_i_init_once(void *foo)
|
|||
struct jffs2_inode_info *f = foo;
|
||||
|
||||
mutex_init(&f->sem);
|
||||
f->target = NULL;
|
||||
inode_init_once(&f->vfs_inode);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1336,9 +1336,9 @@ static int posix_lock_inode(struct inode *inode, struct file_lock *request,
|
|||
locks_wake_up_blocks(left);
|
||||
}
|
||||
out:
|
||||
trace_posix_lock_inode(inode, request, error);
|
||||
spin_unlock(&ctx->flc_lock);
|
||||
percpu_up_read(&file_rwsem);
|
||||
trace_posix_lock_inode(inode, request, error);
|
||||
/*
|
||||
* Free any unused locks.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -377,11 +377,12 @@ void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr,
|
|||
* @target: offset number of an entry in the group (start point)
|
||||
* @bsize: size in bits
|
||||
* @lock: spin lock protecting @bitmap
|
||||
* @wrap: whether to wrap around
|
||||
*/
|
||||
static int nilfs_palloc_find_available_slot(unsigned char *bitmap,
|
||||
unsigned long target,
|
||||
unsigned int bsize,
|
||||
spinlock_t *lock)
|
||||
spinlock_t *lock, bool wrap)
|
||||
{
|
||||
int pos, end = bsize;
|
||||
|
||||
|
|
@ -397,6 +398,8 @@ static int nilfs_palloc_find_available_slot(unsigned char *bitmap,
|
|||
|
||||
end = target;
|
||||
}
|
||||
if (!wrap)
|
||||
return -ENOSPC;
|
||||
|
||||
/* wrap around */
|
||||
for (pos = 0; pos < end; pos++) {
|
||||
|
|
@ -495,9 +498,10 @@ int nilfs_palloc_count_max_entries(struct inode *inode, u64 nused, u64 *nmaxp)
|
|||
* nilfs_palloc_prepare_alloc_entry - prepare to allocate a persistent object
|
||||
* @inode: inode of metadata file using this allocator
|
||||
* @req: nilfs_palloc_req structure exchanged for the allocation
|
||||
* @wrap: whether to wrap around
|
||||
*/
|
||||
int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
|
||||
struct nilfs_palloc_req *req)
|
||||
struct nilfs_palloc_req *req, bool wrap)
|
||||
{
|
||||
struct buffer_head *desc_bh, *bitmap_bh;
|
||||
struct nilfs_palloc_group_desc *desc;
|
||||
|
|
@ -516,7 +520,7 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
|
|||
entries_per_group = nilfs_palloc_entries_per_group(inode);
|
||||
|
||||
for (i = 0; i < ngroups; i += n) {
|
||||
if (group >= ngroups) {
|
||||
if (group >= ngroups && wrap) {
|
||||
/* wrap around */
|
||||
group = 0;
|
||||
maxgroup = nilfs_palloc_group(inode, req->pr_entry_nr,
|
||||
|
|
@ -541,7 +545,13 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
|
|||
bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
|
||||
pos = nilfs_palloc_find_available_slot(
|
||||
bitmap, group_offset,
|
||||
entries_per_group, lock);
|
||||
entries_per_group, lock, wrap);
|
||||
/*
|
||||
* Since the search for a free slot in the
|
||||
* second and subsequent bitmap blocks always
|
||||
* starts from the beginning, the wrap flag
|
||||
* only has an effect on the first search.
|
||||
*/
|
||||
if (pos >= 0) {
|
||||
/* found a free entry */
|
||||
nilfs_palloc_group_desc_add_entries(
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ struct nilfs_palloc_req {
|
|||
struct buffer_head *pr_entry_bh;
|
||||
};
|
||||
|
||||
int nilfs_palloc_prepare_alloc_entry(struct inode *,
|
||||
struct nilfs_palloc_req *);
|
||||
int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
|
||||
struct nilfs_palloc_req *req, bool wrap);
|
||||
void nilfs_palloc_commit_alloc_entry(struct inode *,
|
||||
struct nilfs_palloc_req *);
|
||||
void nilfs_palloc_abort_alloc_entry(struct inode *, struct nilfs_palloc_req *);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ int nilfs_dat_prepare_alloc(struct inode *dat, struct nilfs_palloc_req *req)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = nilfs_palloc_prepare_alloc_entry(dat, req);
|
||||
ret = nilfs_palloc_prepare_alloc_entry(dat, req, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,9 @@ static bool nilfs_check_page(struct page *page)
|
|||
goto Enamelen;
|
||||
if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
|
||||
goto Espan;
|
||||
if (unlikely(p->inode &&
|
||||
NILFS_PRIVATE_INODE(le64_to_cpu(p->inode))))
|
||||
goto Einumber;
|
||||
}
|
||||
if (offs != limit)
|
||||
goto Eend;
|
||||
|
|
@ -168,6 +171,9 @@ Enamelen:
|
|||
goto bad_entry;
|
||||
Espan:
|
||||
error = "directory entry across blocks";
|
||||
goto bad_entry;
|
||||
Einumber:
|
||||
error = "disallowed inode number";
|
||||
bad_entry:
|
||||
nilfs_error(sb,
|
||||
"bad entry in directory #%lu: %s - offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
|
||||
|
|
@ -390,11 +396,39 @@ found:
|
|||
|
||||
struct nilfs_dir_entry *nilfs_dotdot(struct inode *dir, struct page **p)
|
||||
{
|
||||
struct nilfs_dir_entry *de = nilfs_get_page(dir, 0, p);
|
||||
struct page *page;
|
||||
struct nilfs_dir_entry *de, *next_de;
|
||||
size_t limit;
|
||||
char *msg;
|
||||
|
||||
de = nilfs_get_page(dir, 0, &page);
|
||||
if (IS_ERR(de))
|
||||
return NULL;
|
||||
return nilfs_next_entry(de);
|
||||
|
||||
limit = nilfs_last_byte(dir, 0); /* is a multiple of chunk size */
|
||||
if (unlikely(!limit || le64_to_cpu(de->inode) != dir->i_ino ||
|
||||
!nilfs_match(1, ".", de))) {
|
||||
msg = "missing '.'";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
next_de = nilfs_next_entry(de);
|
||||
/*
|
||||
* If "next_de" has not reached the end of the chunk, there is
|
||||
* at least one more record. Check whether it matches "..".
|
||||
*/
|
||||
if (unlikely((char *)next_de == (char *)de + nilfs_chunk_size(dir) ||
|
||||
!nilfs_match(2, "..", next_de))) {
|
||||
msg = "missing '..'";
|
||||
goto fail;
|
||||
}
|
||||
*p = page;
|
||||
return next_de;
|
||||
|
||||
fail:
|
||||
nilfs_error(dir->i_sb, "directory #%lu %s", dir->i_ino, msg);
|
||||
nilfs_put_page(page);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr)
|
||||
|
|
|
|||
|
|
@ -55,13 +55,10 @@ int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino,
|
|||
struct nilfs_palloc_req req;
|
||||
int ret;
|
||||
|
||||
req.pr_entry_nr = 0; /*
|
||||
* 0 says find free inode from beginning
|
||||
* of a group. dull code!!
|
||||
*/
|
||||
req.pr_entry_nr = NILFS_FIRST_INO(ifile->i_sb);
|
||||
req.pr_entry_bh = NULL;
|
||||
|
||||
ret = nilfs_palloc_prepare_alloc_entry(ifile, &req);
|
||||
ret = nilfs_palloc_prepare_alloc_entry(ifile, &req, false);
|
||||
if (!ret) {
|
||||
ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1,
|
||||
&req.pr_entry_bh);
|
||||
|
|
|
|||
|
|
@ -116,9 +116,15 @@ enum {
|
|||
#define NILFS_FIRST_INO(sb) (((struct the_nilfs *)sb->s_fs_info)->ns_first_ino)
|
||||
|
||||
#define NILFS_MDT_INODE(sb, ino) \
|
||||
((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & BIT(ino)))
|
||||
((ino) < NILFS_USER_INO && (NILFS_MDT_INO_BITS & BIT(ino)))
|
||||
#define NILFS_VALID_INODE(sb, ino) \
|
||||
((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & BIT(ino)))
|
||||
((ino) >= NILFS_FIRST_INO(sb) || \
|
||||
((ino) < NILFS_USER_INO && (NILFS_SYS_INO_BITS & BIT(ino))))
|
||||
|
||||
#define NILFS_PRIVATE_INODE(ino) ({ \
|
||||
ino_t __ino = (ino); \
|
||||
((__ino) < NILFS_USER_INO && (__ino) != NILFS_ROOT_INO && \
|
||||
(__ino) != NILFS_SKETCH_INO); })
|
||||
|
||||
/**
|
||||
* struct nilfs_transaction_info: context information for synchronization
|
||||
|
|
|
|||
|
|
@ -420,6 +420,12 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
|
|||
}
|
||||
|
||||
nilfs->ns_first_ino = le32_to_cpu(sbp->s_first_ino);
|
||||
if (nilfs->ns_first_ino < NILFS_USER_INO) {
|
||||
nilfs_err(nilfs->ns_sb,
|
||||
"too small lower limit for non-reserved inode numbers: %u",
|
||||
nilfs->ns_first_ino);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
|
||||
if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) {
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ struct the_nilfs {
|
|||
unsigned long ns_nrsvsegs;
|
||||
unsigned long ns_first_data_block;
|
||||
int ns_inode_size;
|
||||
int ns_first_ino;
|
||||
unsigned int ns_first_ino;
|
||||
u32 ns_crc_seed;
|
||||
|
||||
/* /sys/fs/<nilfs>/<device> */
|
||||
|
|
|
|||
|
|
@ -200,7 +200,8 @@ static int orangefs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|||
(long)new_op->downcall.resp.statfs.files_avail);
|
||||
|
||||
buf->f_type = sb->s_magic;
|
||||
memcpy(&buf->f_fsid, &ORANGEFS_SB(sb)->fs_id, sizeof(buf->f_fsid));
|
||||
buf->f_fsid.val[0] = ORANGEFS_SB(sb)->fs_id;
|
||||
buf->f_fsid.val[1] = ORANGEFS_SB(sb)->id;
|
||||
buf->f_bsize = new_op->downcall.resp.statfs.block_size;
|
||||
buf->f_namelen = ORANGEFS_NAME_MAX;
|
||||
|
||||
|
|
|
|||
|
|
@ -264,6 +264,18 @@
|
|||
*/
|
||||
#define __used __attribute__((__used__))
|
||||
|
||||
/*
|
||||
* Optional: only supported since gcc >= 12
|
||||
*
|
||||
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-uninitialized-variable-attribute
|
||||
* clang: https://clang.llvm.org/docs/AttributeReference.html#uninitialized
|
||||
*/
|
||||
#if __has_attribute(__uninitialized__)
|
||||
# define __uninitialized __attribute__((__uninitialized__))
|
||||
#else
|
||||
# define __uninitialized
|
||||
#endif
|
||||
|
||||
/*
|
||||
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute
|
||||
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute
|
||||
|
|
|
|||
|
|
@ -62,7 +62,13 @@ static inline int fsnotify_perm(struct file *file, int mask)
|
|||
struct inode *inode = file_inode(file);
|
||||
__u32 fsnotify_mask = 0;
|
||||
|
||||
if (file->f_mode & FMODE_NONOTIFY)
|
||||
/*
|
||||
* FMODE_NONOTIFY are fds generated by fanotify itself which should not
|
||||
* generate new events. We also don't want to generate events for
|
||||
* FMODE_PATH fds (involves open & close events) as they are just
|
||||
* handle creation / destruction events and not "real" file events.
|
||||
*/
|
||||
if (file->f_mode & (FMODE_NONOTIFY | FMODE_PATH))
|
||||
return 0;
|
||||
if (!(mask & (MAY_READ | MAY_OPEN)))
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ struct rpc_clnt {
|
|||
#endif
|
||||
struct rpc_xprt_iter cl_xpi;
|
||||
const struct cred *cl_cred;
|
||||
struct super_block *pipefs_sb;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ struct tcp_sock {
|
|||
fastopen_connect:1, /* FASTOPEN_CONNECT sockopt */
|
||||
fastopen_no_cookie:1, /* Allow send/recv SYN+data without a cookie */
|
||||
is_sack_reneg:1, /* in recovery from loss with SACK reneg? */
|
||||
unused:2;
|
||||
fastopen_client_fail:2; /* reason why fastopen failed */
|
||||
u8 nonagle : 4,/* Disable Nagle algorithm? */
|
||||
thin_lto : 1,/* Use linear timeouts for thin streams */
|
||||
recvmsg_inq : 1,/* Indicate # of bytes in queue upon recvmsg */
|
||||
|
|
|
|||
|
|
@ -155,6 +155,14 @@ enum {
|
|||
TCP_QUEUES_NR,
|
||||
};
|
||||
|
||||
/* why fastopen failed from client perspective */
|
||||
enum tcp_fastopen_client_fail {
|
||||
TFO_STATUS_UNSPEC, /* catch-all */
|
||||
TFO_COOKIE_UNAVAILABLE, /* if not in TFO_CLIENT_NO_COOKIE mode */
|
||||
TFO_DATA_NOT_ACKED, /* SYN-ACK did not ack SYN data */
|
||||
TFO_SYN_RETRANSMITTED, /* SYN-ACK did not ack SYN data after timeout */
|
||||
};
|
||||
|
||||
/* for TCP_INFO socket option */
|
||||
#define TCPI_OPT_TIMESTAMPS 1
|
||||
#define TCPI_OPT_SACK 2
|
||||
|
|
@ -211,7 +219,7 @@ struct tcp_info {
|
|||
__u8 tcpi_backoff;
|
||||
__u8 tcpi_options;
|
||||
__u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
|
||||
__u8 tcpi_delivery_rate_app_limited:1;
|
||||
__u8 tcpi_delivery_rate_app_limited:1, tcpi_fastopen_client_fail:2;
|
||||
|
||||
__u32 tcpi_rto;
|
||||
__u32 tcpi_ato;
|
||||
|
|
|
|||
|
|
@ -433,6 +433,8 @@ retry:
|
|||
* Search through everything else, we should not get here often.
|
||||
*/
|
||||
for_each_process(g) {
|
||||
if (atomic_read(&mm->mm_users) <= 1)
|
||||
break;
|
||||
if (g->flags & PF_KTHREAD)
|
||||
continue;
|
||||
for_each_thread(g, c) {
|
||||
|
|
|
|||
|
|
@ -1530,7 +1530,7 @@ static inline void wb_dirty_limits(struct dirty_throttle_control *dtc)
|
|||
*/
|
||||
dtc->wb_thresh = __wb_calc_thresh(dtc);
|
||||
dtc->wb_bg_thresh = dtc->thresh ?
|
||||
div64_u64(dtc->wb_thresh * dtc->bg_thresh, dtc->thresh) : 0;
|
||||
div_u64((u64)dtc->wb_thresh * dtc->bg_thresh, dtc->thresh) : 0;
|
||||
|
||||
/*
|
||||
* In order to avoid the stacked BDI deadlock we need
|
||||
|
|
|
|||
|
|
@ -975,13 +975,19 @@ static void delayed_work(struct work_struct *work)
|
|||
struct ceph_mon_client *monc =
|
||||
container_of(work, struct ceph_mon_client, delayed_work.work);
|
||||
|
||||
dout("monc delayed_work\n");
|
||||
mutex_lock(&monc->mutex);
|
||||
dout("%s mon%d\n", __func__, monc->cur_mon);
|
||||
if (monc->cur_mon < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (monc->hunting) {
|
||||
dout("%s continuing hunt\n", __func__);
|
||||
reopen_session(monc);
|
||||
} else {
|
||||
int is_auth = ceph_auth_is_authenticated(monc->auth);
|
||||
|
||||
dout("%s is_authed %d\n", __func__, is_auth);
|
||||
if (ceph_con_keepalive_expired(&monc->con,
|
||||
CEPH_MONC_PING_TIMEOUT)) {
|
||||
dout("monc keepalive timeout\n");
|
||||
|
|
@ -1006,6 +1012,8 @@ static void delayed_work(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
__schedule_delayed(monc);
|
||||
|
||||
out:
|
||||
mutex_unlock(&monc->mutex);
|
||||
}
|
||||
|
||||
|
|
@ -1118,13 +1126,15 @@ EXPORT_SYMBOL(ceph_monc_init);
|
|||
void ceph_monc_stop(struct ceph_mon_client *monc)
|
||||
{
|
||||
dout("stop\n");
|
||||
cancel_delayed_work_sync(&monc->delayed_work);
|
||||
|
||||
mutex_lock(&monc->mutex);
|
||||
__close_session(monc);
|
||||
monc->hunting = false;
|
||||
monc->cur_mon = -1;
|
||||
mutex_unlock(&monc->mutex);
|
||||
|
||||
cancel_delayed_work_sync(&monc->delayed_work);
|
||||
|
||||
/*
|
||||
* flush msgr queue before we destroy ourselves to ensure that:
|
||||
* - any work that references our embedded con is finished.
|
||||
|
|
|
|||
|
|
@ -1088,6 +1088,7 @@ static int inet_diag_dump_compat(struct sk_buff *skb,
|
|||
req.sdiag_family = AF_UNSPEC; /* compatibility */
|
||||
req.sdiag_protocol = inet_diag_type2proto(cb->nlh->nlmsg_type);
|
||||
req.idiag_ext = rc->idiag_ext;
|
||||
req.pad = 0;
|
||||
req.idiag_states = rc->idiag_states;
|
||||
req.id = rc->id;
|
||||
|
||||
|
|
@ -1106,6 +1107,7 @@ static int inet_diag_get_exact_compat(struct sk_buff *in_skb,
|
|||
req.sdiag_family = rc->idiag_family;
|
||||
req.sdiag_protocol = inet_diag_type2proto(nlh->nlmsg_type);
|
||||
req.idiag_ext = rc->idiag_ext;
|
||||
req.pad = 0;
|
||||
req.idiag_states = rc->idiag_states;
|
||||
req.id = rc->id;
|
||||
|
||||
|
|
|
|||
|
|
@ -2707,6 +2707,7 @@ int tcp_disconnect(struct sock *sk, int flags)
|
|||
/* Clean up fastopen related fields */
|
||||
tcp_free_fastopen_req(tp);
|
||||
inet->defer_connect = 0;
|
||||
tp->fastopen_client_fail = 0;
|
||||
|
||||
WARN_ON(inet->inet_num && !icsk->icsk_bind_hash);
|
||||
|
||||
|
|
@ -3354,6 +3355,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
|
|||
info->tcpi_reord_seen = tp->reord_seen;
|
||||
info->tcpi_rcv_ooopack = tp->rcv_ooopack;
|
||||
info->tcpi_snd_wnd = tp->snd_wnd;
|
||||
info->tcpi_fastopen_client_fail = tp->fastopen_client_fail;
|
||||
unlock_sock_fast(sk, slow);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tcp_get_info);
|
||||
|
|
|
|||
|
|
@ -446,7 +446,10 @@ bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
|
|||
cookie->len = -1;
|
||||
return true;
|
||||
}
|
||||
return cookie->len > 0;
|
||||
if (cookie->len > 0)
|
||||
return true;
|
||||
tcp_sk(sk)->fastopen_client_fail = TFO_COOKIE_UNAVAILABLE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This function checks if we want to defer sending SYN until the first
|
||||
|
|
|
|||
|
|
@ -1906,7 +1906,7 @@ static void tcp_check_reno_reordering(struct sock *sk, const int addend)
|
|||
|
||||
/* Emulate SACKs for SACKless connection: account for a new dupack. */
|
||||
|
||||
static void tcp_add_reno_sack(struct sock *sk, int num_dupack)
|
||||
static void tcp_add_reno_sack(struct sock *sk, int num_dupack, bool ece_ack)
|
||||
{
|
||||
if (num_dupack) {
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
|
@ -1924,7 +1924,7 @@ static void tcp_add_reno_sack(struct sock *sk, int num_dupack)
|
|||
|
||||
/* Account for ACK, ACKing some data in Reno Recovery phase. */
|
||||
|
||||
static void tcp_remove_reno_sacks(struct sock *sk, int acked)
|
||||
static void tcp_remove_reno_sacks(struct sock *sk, int acked, bool ece_ack)
|
||||
{
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
||||
|
|
@ -1957,8 +1957,16 @@ void tcp_clear_retrans(struct tcp_sock *tp)
|
|||
static inline void tcp_init_undo(struct tcp_sock *tp)
|
||||
{
|
||||
tp->undo_marker = tp->snd_una;
|
||||
|
||||
/* Retransmission still in flight may cause DSACKs later. */
|
||||
tp->undo_retrans = tp->retrans_out ? : -1;
|
||||
/* First, account for regular retransmits in flight: */
|
||||
tp->undo_retrans = tp->retrans_out;
|
||||
/* Next, account for TLP retransmits in flight: */
|
||||
if (tp->tlp_high_seq && tp->tlp_retrans)
|
||||
tp->undo_retrans++;
|
||||
/* Finally, avoid 0, because undo_retrans==0 means "can undo now": */
|
||||
if (!tp->undo_retrans)
|
||||
tp->undo_retrans = -1;
|
||||
}
|
||||
|
||||
static bool tcp_is_rack(const struct sock *sk)
|
||||
|
|
@ -2037,6 +2045,7 @@ void tcp_enter_loss(struct sock *sk)
|
|||
|
||||
tcp_set_ca_state(sk, TCP_CA_Loss);
|
||||
tp->high_seq = tp->snd_nxt;
|
||||
tp->tlp_high_seq = 0;
|
||||
tcp_ecn_queue_cwr(tp);
|
||||
|
||||
/* F-RTO RFC5682 sec 3.1 step 1: retransmit SND.UNA if no previous
|
||||
|
|
@ -2203,8 +2212,7 @@ static bool tcp_time_to_recover(struct sock *sk, int flag)
|
|||
}
|
||||
|
||||
/* Detect loss in event "A" above by marking head of queue up as lost.
|
||||
* For non-SACK(Reno) senders, the first "packets" number of segments
|
||||
* are considered lost. For RFC3517 SACK, a segment is considered lost if it
|
||||
* For RFC3517 SACK, a segment is considered lost if it
|
||||
* has at least tp->reordering SACKed seqments above it; "packets" refers to
|
||||
* the maximum SACKed segments to pass before reaching this limit.
|
||||
*/
|
||||
|
|
@ -2212,10 +2220,9 @@ 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, lost;
|
||||
unsigned int mss;
|
||||
int cnt;
|
||||
/* 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;
|
||||
const u32 loss_high = tp->snd_nxt;
|
||||
|
||||
WARN_ON(packets > tp->packets_out);
|
||||
skb = tp->lost_skb_hint;
|
||||
|
|
@ -2238,26 +2245,11 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
|
|||
if (after(TCP_SKB_CB(skb)->end_seq, loss_high))
|
||||
break;
|
||||
|
||||
oldcnt = cnt;
|
||||
if (tcp_is_reno(tp) ||
|
||||
(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
|
||||
if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)
|
||||
cnt += tcp_skb_pcount(skb);
|
||||
|
||||
if (cnt > packets) {
|
||||
if (tcp_is_sack(tp) ||
|
||||
(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) ||
|
||||
(oldcnt >= packets))
|
||||
break;
|
||||
|
||||
mss = tcp_skb_mss(skb);
|
||||
/* If needed, chop off the prefix to mark as lost. */
|
||||
lost = (packets - oldcnt) * mss;
|
||||
if (lost < skb->len &&
|
||||
tcp_fragment(sk, TCP_FRAG_IN_RTX_QUEUE, skb,
|
||||
lost, mss, GFP_ATOMIC) < 0)
|
||||
break;
|
||||
cnt = packets;
|
||||
}
|
||||
if (cnt > packets)
|
||||
break;
|
||||
|
||||
tcp_skb_mark_lost(tp, skb);
|
||||
|
||||
|
|
@ -2747,15 +2739,24 @@ static void tcp_process_loss(struct sock *sk, int flag, int num_dupack,
|
|||
* delivered. Lower inflight to clock out (re)tranmissions.
|
||||
*/
|
||||
if (after(tp->snd_nxt, tp->high_seq) && num_dupack)
|
||||
tcp_add_reno_sack(sk, num_dupack);
|
||||
tcp_add_reno_sack(sk, num_dupack, flag & FLAG_ECE);
|
||||
else if (flag & FLAG_SND_UNA_ADVANCED)
|
||||
tcp_reset_reno_sack(tp);
|
||||
}
|
||||
*rexmit = REXMIT_LOST;
|
||||
}
|
||||
|
||||
static bool tcp_force_fast_retransmit(struct sock *sk)
|
||||
{
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
||||
return after(tcp_highest_sack_seq(tp),
|
||||
tp->snd_una + tp->reordering * tp->mss_cache);
|
||||
}
|
||||
|
||||
/* Undo during fast recovery after partial ACK. */
|
||||
static bool tcp_try_undo_partial(struct sock *sk, u32 prior_snd_una)
|
||||
static bool tcp_try_undo_partial(struct sock *sk, u32 prior_snd_una,
|
||||
bool *do_lost)
|
||||
{
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
||||
|
|
@ -2780,7 +2781,9 @@ static bool tcp_try_undo_partial(struct sock *sk, u32 prior_snd_una)
|
|||
tcp_undo_cwnd_reduction(sk, true);
|
||||
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPPARTIALUNDO);
|
||||
tcp_try_keep_open(sk);
|
||||
return true;
|
||||
} else {
|
||||
/* Partial ACK arrived. Force fast retransmit. */
|
||||
*do_lost = tcp_force_fast_retransmit(sk);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2804,14 +2807,6 @@ static void tcp_identify_packet_loss(struct sock *sk, int *ack_flag)
|
|||
}
|
||||
}
|
||||
|
||||
static bool tcp_force_fast_retransmit(struct sock *sk)
|
||||
{
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
|
||||
return after(tcp_highest_sack_seq(tp),
|
||||
tp->snd_una + tp->reordering * tp->mss_cache);
|
||||
}
|
||||
|
||||
/* Process an event, which can update packets-in-flight not trivially.
|
||||
* Main goal of this function is to calculate new estimate for left_out,
|
||||
* taking into account both packets sitting in receiver's buffer and
|
||||
|
|
@ -2830,6 +2825,7 @@ static void tcp_fastretrans_alert(struct sock *sk, const u32 prior_snd_una,
|
|||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
int fast_rexmit = 0, flag = *ack_flag;
|
||||
bool ece_ack = flag & FLAG_ECE;
|
||||
bool do_lost = num_dupack || ((flag & FLAG_DATA_SACKED) &&
|
||||
tcp_force_fast_retransmit(sk));
|
||||
|
||||
|
|
@ -2838,7 +2834,7 @@ static void tcp_fastretrans_alert(struct sock *sk, const u32 prior_snd_una,
|
|||
|
||||
/* Now state machine starts.
|
||||
* A. ECE, hence prohibit cwnd undoing, the reduction is required. */
|
||||
if (flag & FLAG_ECE)
|
||||
if (ece_ack)
|
||||
tp->prior_ssthresh = 0;
|
||||
|
||||
/* B. In all the states check for reneging SACKs. */
|
||||
|
|
@ -2879,19 +2875,22 @@ static void tcp_fastretrans_alert(struct sock *sk, const u32 prior_snd_una,
|
|||
case TCP_CA_Recovery:
|
||||
if (!(flag & FLAG_SND_UNA_ADVANCED)) {
|
||||
if (tcp_is_reno(tp))
|
||||
tcp_add_reno_sack(sk, num_dupack);
|
||||
} else {
|
||||
if (tcp_try_undo_partial(sk, prior_snd_una))
|
||||
return;
|
||||
/* Partial ACK arrived. Force fast retransmit. */
|
||||
do_lost = tcp_is_reno(tp) ||
|
||||
tcp_force_fast_retransmit(sk);
|
||||
}
|
||||
if (tcp_try_undo_dsack(sk)) {
|
||||
tcp_try_keep_open(sk);
|
||||
tcp_add_reno_sack(sk, num_dupack, ece_ack);
|
||||
} else if (tcp_try_undo_partial(sk, prior_snd_una, &do_lost))
|
||||
return;
|
||||
}
|
||||
|
||||
if (tcp_try_undo_dsack(sk))
|
||||
tcp_try_to_open(sk, flag);
|
||||
|
||||
tcp_identify_packet_loss(sk, ack_flag);
|
||||
if (icsk->icsk_ca_state != TCP_CA_Recovery) {
|
||||
if (!tcp_time_to_recover(sk, flag))
|
||||
return;
|
||||
/* Undo reverts the recovery state. If loss is evident,
|
||||
* starts a new recovery (e.g. reordering then loss);
|
||||
*/
|
||||
tcp_enter_recovery(sk, ece_ack);
|
||||
}
|
||||
break;
|
||||
case TCP_CA_Loss:
|
||||
tcp_process_loss(sk, flag, num_dupack, rexmit);
|
||||
|
|
@ -2905,7 +2904,7 @@ static void tcp_fastretrans_alert(struct sock *sk, const u32 prior_snd_una,
|
|||
if (tcp_is_reno(tp)) {
|
||||
if (flag & FLAG_SND_UNA_ADVANCED)
|
||||
tcp_reset_reno_sack(tp);
|
||||
tcp_add_reno_sack(sk, num_dupack);
|
||||
tcp_add_reno_sack(sk, num_dupack, ece_ack);
|
||||
}
|
||||
|
||||
if (icsk->icsk_ca_state <= TCP_CA_Disorder)
|
||||
|
|
@ -2929,7 +2928,7 @@ static void tcp_fastretrans_alert(struct sock *sk, const u32 prior_snd_una,
|
|||
}
|
||||
|
||||
/* Otherwise enter Recovery state */
|
||||
tcp_enter_recovery(sk, (flag & FLAG_ECE));
|
||||
tcp_enter_recovery(sk, ece_ack);
|
||||
fast_rexmit = 1;
|
||||
}
|
||||
|
||||
|
|
@ -3107,7 +3106,7 @@ static void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb,
|
|||
*/
|
||||
static int tcp_clean_rtx_queue(struct sock *sk, u32 prior_fack,
|
||||
u32 prior_snd_una,
|
||||
struct tcp_sacktag_state *sack)
|
||||
struct tcp_sacktag_state *sack, bool ece_ack)
|
||||
{
|
||||
const struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
u64 first_ackt, last_ackt;
|
||||
|
|
@ -3245,7 +3244,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, u32 prior_fack,
|
|||
}
|
||||
|
||||
if (tcp_is_reno(tp)) {
|
||||
tcp_remove_reno_sacks(sk, pkts_acked);
|
||||
tcp_remove_reno_sacks(sk, pkts_acked, ece_ack);
|
||||
|
||||
/* If any of the cumulatively ACKed segments was
|
||||
* retransmitted, non-SACK case cannot confirm that
|
||||
|
|
@ -3754,7 +3753,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
|||
goto no_queue;
|
||||
|
||||
/* See if we can take anything off of the retransmit queue. */
|
||||
flag |= tcp_clean_rtx_queue(sk, prior_fack, prior_snd_una, &sack_state);
|
||||
flag |= tcp_clean_rtx_queue(sk, prior_fack, prior_snd_una, &sack_state,
|
||||
flag & FLAG_ECE);
|
||||
|
||||
tcp_rack_update_reo_wnd(sk, &rs);
|
||||
|
||||
|
|
@ -5907,6 +5907,10 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
|
|||
tcp_fastopen_cache_set(sk, mss, cookie, syn_drop, try_exp);
|
||||
|
||||
if (data) { /* Retransmit unacked data in SYN */
|
||||
if (tp->total_retrans)
|
||||
tp->fastopen_client_fail = TFO_SYN_RETRANSMITTED;
|
||||
else
|
||||
tp->fastopen_client_fail = TFO_DATA_NOT_ACKED;
|
||||
skb_rbtree_walk_from(data) {
|
||||
if (__tcp_retransmit_skb(sk, data, 1))
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -614,6 +614,7 @@ static const struct nla_policy tcp_metrics_nl_policy[TCP_METRICS_ATTR_MAX + 1] =
|
|||
[TCP_METRICS_ATTR_ADDR_IPV4] = { .type = NLA_U32, },
|
||||
[TCP_METRICS_ATTR_ADDR_IPV6] = { .type = NLA_BINARY,
|
||||
.len = sizeof(struct in6_addr), },
|
||||
[TCP_METRICS_ATTR_SADDR_IPV4] = { .type = NLA_U32, },
|
||||
/* Following attributes are not received for GET/DEL,
|
||||
* we keep them for reference
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -434,6 +434,39 @@ static void tcp_fastopen_synack_timer(struct sock *sk, struct request_sock *req)
|
|||
TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX);
|
||||
}
|
||||
|
||||
static bool tcp_rtx_probe0_timed_out(const struct sock *sk,
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
const struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
u32 user_timeout = READ_ONCE(icsk->icsk_user_timeout);
|
||||
const struct tcp_sock *tp = tcp_sk(sk);
|
||||
int timeout = TCP_RTO_MAX * 2;
|
||||
u32 rtx_delta;
|
||||
s32 rcv_delta;
|
||||
|
||||
rtx_delta = (u32)msecs_to_jiffies(tcp_time_stamp(tp) -
|
||||
(tp->retrans_stamp ?: tcp_skb_timestamp(skb)));
|
||||
|
||||
if (user_timeout) {
|
||||
/* If user application specified a TCP_USER_TIMEOUT,
|
||||
* it does not want win 0 packets to 'reset the timer'
|
||||
* while retransmits are not making progress.
|
||||
*/
|
||||
if (rtx_delta > user_timeout)
|
||||
return true;
|
||||
timeout = min_t(u32, timeout, msecs_to_jiffies(user_timeout));
|
||||
}
|
||||
|
||||
/* Note: timer interrupt might have been delayed by at least one jiffy,
|
||||
* and tp->rcv_tstamp might very well have been written recently.
|
||||
* rcv_delta can thus be negative.
|
||||
*/
|
||||
rcv_delta = icsk->icsk_timeout - tp->rcv_tstamp;
|
||||
if (rcv_delta <= timeout)
|
||||
return false;
|
||||
|
||||
return rtx_delta > timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* tcp_retransmit_timer() - The TCP retransmit timeout handler
|
||||
|
|
@ -452,6 +485,7 @@ void tcp_retransmit_timer(struct sock *sk)
|
|||
struct net *net = sock_net(sk);
|
||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
struct request_sock *req;
|
||||
struct sk_buff *skb;
|
||||
|
||||
req = rcu_dereference_protected(tp->fastopen_rsk,
|
||||
lockdep_sock_is_held(sk));
|
||||
|
|
@ -464,10 +498,13 @@ void tcp_retransmit_timer(struct sock *sk)
|
|||
*/
|
||||
return;
|
||||
}
|
||||
if (!tp->packets_out || WARN_ON_ONCE(tcp_rtx_queue_empty(sk)))
|
||||
|
||||
if (!tp->packets_out)
|
||||
return;
|
||||
|
||||
tp->tlp_high_seq = 0;
|
||||
skb = tcp_rtx_queue_head(sk);
|
||||
if (WARN_ON_ONCE(!skb))
|
||||
return;
|
||||
|
||||
if (!tp->snd_wnd && !sock_flag(sk, SOCK_DEAD) &&
|
||||
!((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) {
|
||||
|
|
@ -493,12 +530,12 @@ void tcp_retransmit_timer(struct sock *sk)
|
|||
tp->snd_una, tp->snd_nxt);
|
||||
}
|
||||
#endif
|
||||
if (tcp_jiffies32 - tp->rcv_tstamp > TCP_RTO_MAX) {
|
||||
if (tcp_rtx_probe0_timed_out(sk, skb)) {
|
||||
tcp_write_err(sk);
|
||||
goto out;
|
||||
}
|
||||
tcp_enter_loss(sk);
|
||||
tcp_retransmit_skb(sk, tcp_rtx_queue_head(sk), 1);
|
||||
tcp_retransmit_skb(sk, skb, 1);
|
||||
__sk_dst_reset(sk);
|
||||
goto out_reset_timer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -313,6 +313,8 @@ found:
|
|||
goto fail_unlock;
|
||||
}
|
||||
|
||||
sock_set_flag(sk, SOCK_RCU_FREE);
|
||||
|
||||
sk_add_node_rcu(sk, &hslot->head);
|
||||
hslot->count++;
|
||||
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
|
||||
|
|
@ -329,7 +331,7 @@ found:
|
|||
hslot2->count++;
|
||||
spin_unlock(&hslot2->lock);
|
||||
}
|
||||
sock_set_flag(sk, SOCK_RCU_FREE);
|
||||
|
||||
error = 0;
|
||||
fail_unlock:
|
||||
spin_unlock_bh(&hslot->lock);
|
||||
|
|
|
|||
|
|
@ -7163,6 +7163,7 @@ static int sctp_getsockopt_assoc_ids(struct sock *sk, int len,
|
|||
struct sctp_sock *sp = sctp_sk(sk);
|
||||
struct sctp_association *asoc;
|
||||
struct sctp_assoc_ids *ids;
|
||||
size_t ids_size;
|
||||
u32 num = 0;
|
||||
|
||||
if (sctp_style(sk, TCP))
|
||||
|
|
@ -7175,11 +7176,11 @@ static int sctp_getsockopt_assoc_ids(struct sock *sk, int len,
|
|||
num++;
|
||||
}
|
||||
|
||||
if (len < sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num)
|
||||
ids_size = struct_size(ids, gaids_assoc_id, num);
|
||||
if (len < ids_size)
|
||||
return -EINVAL;
|
||||
|
||||
len = sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num;
|
||||
|
||||
len = ids_size;
|
||||
ids = kmalloc(len, GFP_USER | __GFP_NOWARN);
|
||||
if (unlikely(!ids))
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -113,7 +113,8 @@ static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt)
|
|||
|
||||
pipefs_sb = rpc_get_sb_net(net);
|
||||
if (pipefs_sb) {
|
||||
__rpc_clnt_remove_pipedir(clnt);
|
||||
if (pipefs_sb == clnt->pipefs_sb)
|
||||
__rpc_clnt_remove_pipedir(clnt);
|
||||
rpc_put_sb_net(net);
|
||||
}
|
||||
}
|
||||
|
|
@ -153,6 +154,8 @@ rpc_setup_pipedir(struct super_block *pipefs_sb, struct rpc_clnt *clnt)
|
|||
{
|
||||
struct dentry *dentry;
|
||||
|
||||
clnt->pipefs_sb = pipefs_sb;
|
||||
|
||||
if (clnt->cl_program->pipe_dir_name != NULL) {
|
||||
dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt);
|
||||
if (IS_ERR(dentry))
|
||||
|
|
|
|||
|
|
@ -8331,6 +8331,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
|
||||
SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
|
||||
SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x10ec, 0x11bc, "VAIO VJFE-IL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||
SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
||||
SND_PCI_QUIRK(0x10ec, 0x124c, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
||||
SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
||||
|
|
@ -8494,6 +8495,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||
SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),
|
||||
SND_PCI_QUIRK(0x2782, 0x1707, "Vaio VJFE-ADL", ALC298_FIXUP_SPK_VOLUME),
|
||||
SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC),
|
||||
|
|
@ -9909,6 +9911,7 @@ enum {
|
|||
ALC897_FIXUP_LENOVO_HEADSET_MODE,
|
||||
ALC897_FIXUP_HEADSET_MIC_PIN2,
|
||||
ALC897_FIXUP_UNIS_H3C_X500S,
|
||||
ALC897_FIXUP_HEADSET_MIC_PIN3,
|
||||
};
|
||||
|
||||
static const struct hda_fixup alc662_fixups[] = {
|
||||
|
|
@ -10355,10 +10358,18 @@ static const struct hda_fixup alc662_fixups[] = {
|
|||
{}
|
||||
},
|
||||
},
|
||||
[ALC897_FIXUP_HEADSET_MIC_PIN3] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x19, 0x03a11050 }, /* use as headset mic */
|
||||
{ }
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc662_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
|
||||
SND_PCI_QUIRK(0x1019, 0x9859, "JP-IK LEAP W502", ALC897_FIXUP_HEADSET_MIC_PIN3),
|
||||
SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ static bool cfg_rx;
|
|||
static int cfg_runtime_ms = 4200;
|
||||
static int cfg_verbose;
|
||||
static int cfg_waittime_ms = 500;
|
||||
static int cfg_notification_limit = 32;
|
||||
static bool cfg_zerocopy;
|
||||
|
||||
static socklen_t cfg_alen;
|
||||
|
|
@ -95,6 +96,7 @@ static char payload[IP_MAXPACKET];
|
|||
static long packets, bytes, completions, expected_completions;
|
||||
static int zerocopied = -1;
|
||||
static uint32_t next_completion;
|
||||
static uint32_t sends_since_notify;
|
||||
|
||||
static unsigned long gettimeofday_ms(void)
|
||||
{
|
||||
|
|
@ -208,6 +210,7 @@ static bool do_sendmsg(int fd, struct msghdr *msg, bool do_zerocopy, int domain)
|
|||
error(1, errno, "send");
|
||||
if (cfg_verbose && ret != len)
|
||||
fprintf(stderr, "send: ret=%u != %u\n", ret, len);
|
||||
sends_since_notify++;
|
||||
|
||||
if (len) {
|
||||
packets++;
|
||||
|
|
@ -435,7 +438,7 @@ static bool do_recv_completion(int fd, int domain)
|
|||
/* Detect notification gaps. These should not happen often, if at all.
|
||||
* Gaps can occur due to drops, reordering and retransmissions.
|
||||
*/
|
||||
if (lo != next_completion)
|
||||
if (cfg_verbose && lo != next_completion)
|
||||
fprintf(stderr, "gap: %u..%u does not append to %u\n",
|
||||
lo, hi, next_completion);
|
||||
next_completion = hi + 1;
|
||||
|
|
@ -460,6 +463,7 @@ static bool do_recv_completion(int fd, int domain)
|
|||
static void do_recv_completions(int fd, int domain)
|
||||
{
|
||||
while (do_recv_completion(fd, domain)) {}
|
||||
sends_since_notify = 0;
|
||||
}
|
||||
|
||||
/* Wait for all remaining completions on the errqueue */
|
||||
|
|
@ -549,6 +553,9 @@ static void do_tx(int domain, int type, int protocol)
|
|||
else
|
||||
do_sendmsg(fd, &msg, cfg_zerocopy, domain);
|
||||
|
||||
if (cfg_zerocopy && sends_since_notify >= cfg_notification_limit)
|
||||
do_recv_completions(fd, domain);
|
||||
|
||||
while (!do_poll(fd, POLLOUT)) {
|
||||
if (cfg_zerocopy)
|
||||
do_recv_completions(fd, domain);
|
||||
|
|
@ -708,7 +715,7 @@ static void parse_opts(int argc, char **argv)
|
|||
|
||||
cfg_payload_len = max_payload_len;
|
||||
|
||||
while ((c = getopt(argc, argv, "46c:C:D:i:mp:rs:S:t:vz")) != -1) {
|
||||
while ((c = getopt(argc, argv, "46c:C:D:i:l:mp:rs:S:t:vz")) != -1) {
|
||||
switch (c) {
|
||||
case '4':
|
||||
if (cfg_family != PF_UNSPEC)
|
||||
|
|
@ -736,6 +743,9 @@ static void parse_opts(int argc, char **argv)
|
|||
if (cfg_ifindex == 0)
|
||||
error(1, errno, "invalid iface: %s", optarg);
|
||||
break;
|
||||
case 'l':
|
||||
cfg_notification_limit = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'm':
|
||||
cfg_cork_mixed = true;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue