summaryrefslogtreecommitdiff
path: root/net/sunrpc/sched.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@google.com>2019-11-25 17:44:35 +0100
committerGreg Kroah-Hartman <gregkh@google.com>2019-11-25 17:44:35 +0100
commit40ef73d67ad90b656e19b74734d2f2c4c966cf7b (patch)
treec82895eb9b8a2ae1094ea647d93fb92882c84ade /net/sunrpc/sched.c
parenta4d443b76f662953674703f370c312461b9b7b55 (diff)
parent48a16935fdcdb0926ed5e743a9d8d238bbc9c243 (diff)
Merge 4.4.203 into android-4.4-p
Changes in 4.4.203 slip: Fix memory leak in slip_open error path ax88172a: fix information leak on short answers ALSA: usb-audio: Fix missing error check at mixer resolution test ALSA: usb-audio: not submit urb for stopped endpoint Input: ff-memless - kill timer in destroy() ecryptfs_lookup_interpose(): lower_dentry->d_inode is not stable ecryptfs_lookup_interpose(): lower_dentry->d_parent is not stable either iommu/vt-d: Fix QI_DEV_IOTLB_PFSID and QI_DEV_EIOTLB_PFSID macros mm: memcg: switch to css_tryget() in get_mem_cgroup_from_mm() mm: hugetlb: switch to css_tryget() in hugetlb_cgroup_charge_cgroup() mmc: sdhci-of-at91: fix quirk2 overwrite iio: dac: mcp4922: fix error handling in mcp4922_write_raw ALSA: pcm: signedness bug in snd_pcm_plug_alloc() ARM: dts: at91/trivial: Fix USART1 definition for at91sam9g45 ALSA: seq: Do error checks at creating system ports gfs2: Don't set GFS2_RDF_UPTODATE when the lvb is updated ASoC: dpcm: Properly initialise hw->rate_max MIPS: BCM47XX: Enable USB power on Netgear WNDR3400v3 ARM: dts: exynos: Fix sound in Snow-rev5 Chromebook i40e: use correct length for strncpy i40e: hold the rtnl lock on clearing interrupt scheme i40e: Prevent deleting MAC address from VF when set by PF ARM: dts: pxa: fix power i2c base address rtl8187: Fix warning generated when strncpy() destination length matches the sixe argument net: lan78xx: Bail out if lan78xx_get_endpoints fails ASoC: sgtl5000: avoid division by zero if lo_vag is zero ath10k: wmi: disable softirq's while calling ieee80211_rx mips: txx9: fix iounmap related issue of: make PowerMac cache node search conditional on CONFIG_PPC_PMAC ARM: dts: omap3-gta04: give spi_lcd node a label so that we can overwrite in other DTS files ARM: dts: omap3-gta04: tvout: enable as display1 alias ARM: dts: omap3-gta04: make NAND partitions compatible with recent U-Boot ARM: dts: omap3-gta04: keep vpll2 always on dmaengine: dma-jz4780: Further residue status fix signal: Always ignore SIGKILL and SIGSTOP sent to the global init signal: Properly deliver SIGILL from uprobes signal: Properly deliver SIGSEGV from x86 uprobes scsi: sym53c8xx: fix NULL pointer dereference panic in sym_int_sir() ARM: imx6: register pm_power_off handler if "fsl,pmic-stby-poweroff" is set scsi: pm80xx: Corrected dma_unmap_sg() parameter scsi: pm80xx: Fixed system hang issue during kexec boot kprobes: Don't call BUG_ON() if there is a kprobe in use on free list nvmem: core: return error code instead of NULL from nvmem_device_get media: fix: media: pci: meye: validate offset to avoid arbitrary access ALSA: intel8x0m: Register irq handler after register initializations pinctrl: at91-pio4: fix has_config check in atmel_pctl_dt_subnode_to_map() llc: avoid blocking in llc_sap_close() powerpc/vdso: Correct call frame information ARM: dts: socfpga: Fix I2C bus unit-address error pinctrl: at91: don't use the same irqchip with multiple gpiochips cxgb4: Fix endianness issue in t4_fwcache() power: supply: ab8500_fg: silence uninitialized variable warnings power: supply: max8998-charger: Fix platform data retrieval kernfs: Fix range checks in kernfs_get_target_path s390/qeth: invoke softirqs after napi_schedule() PCI/ACPI: Correct error message for ASPM disabling serial: mxs-auart: Fix potential infinite loop powerpc/iommu: Avoid derefence before pointer check powerpc/64s/hash: Fix stab_rr off by one initialization powerpc/pseries: Disable CPU hotplug across migrations libfdt: Ensure INT_MAX is defined in libfdt_env.h power: supply: twl4030_charger: fix charging current out-of-bounds power: supply: twl4030_charger: disable eoc interrupt on linear charge net: toshiba: fix return type of ndo_start_xmit function net: xilinx: fix return type of ndo_start_xmit function net: broadcom: fix return type of ndo_start_xmit function net: amd: fix return type of ndo_start_xmit function usb: chipidea: Fix otg event handler ARM: dts: am335x-evm: fix number of cpsw ARM: dts: ux500: Correct SCU unit address ARM: dts: ux500: Fix LCDA clock line muxing ARM: dts: ste: Fix SPI controller node names cpufeature: avoid warning when compiling with clang bnx2x: Ignore bandwidth attention in single function mode net: micrel: fix return type of ndo_start_xmit function x86/CPU: Use correct macros for Cyrix calls MIPS: kexec: Relax memory restriction media: pci: ivtv: Fix a sleep-in-atomic-context bug in ivtv_yuv_init() media: davinci: Fix implicit enum conversion warning usb: gadget: uvc: configfs: Drop leaked references to config items usb: gadget: uvc: configfs: Prevent format changes after linking header usb: gadget: uvc: Factor out video USB request queueing usb: gadget: uvc: Only halt video streaming endpoint in bulk mode misc: kgdbts: Fix restrict error misc: genwqe: should return proper error value. vfio/pci: Fix potential memory leak in vfio_msi_cap_len scsi: libsas: always unregister the old device if going to discover new ARM: dts: tegra30: fix xcvr-setup-use-fuses ARM: tegra: apalis_t30: fix mmc1 cmd pull-up net: smsc: fix return type of ndo_start_xmit function EDAC: Raise the maximum number of memory controllers Bluetooth: L2CAP: Detect if remote is not able to use the whole MPS arm64: dts: amd: Fix SPI bus warnings fuse: use READ_ONCE on congestion_threshold and max_background Bluetooth: hci_ldisc: Fix null pointer derefence in case of early data Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in hci_uart_set_proto() memfd: Use radix_tree_deref_slot_protected to avoid the warning. slcan: Fix memory leak in error path net: cdc_ncm: Signedness bug in cdc_ncm_set_dgram_size() x86/atomic: Fix smp_mb__{before,after}_atomic() apparmor: fix uninitialized lsm_audit member apparmor: fix update the mtime of the profile file on replacement apparmor: fix module parameters can be changed after policy is locked kprobes/x86: Prohibit probing on exception masking instructions uprobes/x86: Prohibit probing on MOV SS instruction fbdev: Remove unused SH-Mobile HDMI driver fbdev: Ditch fb_edid_add_monspecs block: introduce blk_rq_is_passthrough libata: have ata_scsi_rw_xlat() fail invalid passthrough requests net: ovs: fix return type of ndo_start_xmit function f2fs: return correct errno in f2fs_gc SUNRPC: Fix priority queue fairness ath10k: fix vdev-start timeout on error ath9k: fix reporting calculated new FFT upper max usb: gadget: udc: fotg210-udc: Fix a sleep-in-atomic-context bug in fotg210_get_status() nl80211: Fix a GET_KEY reply attribute dmaengine: ep93xx: Return proper enum in ep93xx_dma_chan_direction dmaengine: timb_dma: Use proper enum in td_prep_slave_sg mei: samples: fix a signedness bug in amt_host_if_call() cxgb4: Use proper enum in cxgb4_dcb_handle_fw_update cxgb4: Use proper enum in IEEE_FAUX_SYNC powerpc/pseries: Fix DTL buffer registration powerpc/pseries: Fix how we iterate over the DTL entries mtd: rawnand: sh_flctl: Use proper enum for flctl_dma_fifo0_transfer ixgbe: Fix crash with VFs and flow director on interface flap IB/mthca: Fix error return code in __mthca_init_one() ata: ep93xx: Use proper enums for directions ALSA: hda/sigmatel - Disable automute for Elo VuPoint KVM: PPC: Book3S PR: Exiting split hack mode needs to fixup both PC and LR USB: serial: cypress_m8: fix interrupt-out transfer length mtd: physmap_of: Release resources on error brcmfmac: fix full timeout waiting for action frame on-channel tx NFSv4.x: fix lock recovery during delegation recall dmaengine: ioat: fix prototype of ioat_enumerate_channels Input: st1232 - set INPUT_PROP_DIRECT property x86/olpc: Fix build error with CONFIG_MFD_CS5535=m crypto: mxs-dcp - Fix SHA null hashes and output length crypto: mxs-dcp - Fix AES issues ACPI / SBS: Fix rare oops when removing modules fbdev: sbuslib: use checked version of put_user() fbdev: sbuslib: integer overflow in sbusfb_ioctl_helper() bcache: recal cached_dev_sectors on detach proc/vmcore: Fix i386 build error of missing copy_oldmem_page_encrypted() backlight: lm3639: Unconditionally call led_classdev_unregister printk: Give error on attempt to set log buffer length to over 2G media: isif: fix a NULL pointer dereference bug GFS2: Flush the GFS2 delete workqueue before stopping the kernel threads media: cx231xx: fix potential sign-extension overflow on large shift x86/kexec: Correct KEXEC_BACKUP_SRC_END off-by-one error gpio: syscon: Fix possible NULL ptr usage spi: spidev: Fix OF tree warning logic ARM: 8802/1: Call syscall_trace_exit even when system call skipped hwmon: (pwm-fan) Silence error on probe deferral mac80211: minstrel: fix CCK rate group streams value spi: rockchip: initialize dma_slave_config properly arm64: uaccess: Ensure PAN is re-enabled after unhandled uaccess fault Linux 4.4.203 Change-Id: Icba08e9fbb6f47274ee6fcf1023a1469cd8550d3 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'net/sunrpc/sched.c')
-rw-r--r--net/sunrpc/sched.c109
1 files changed, 54 insertions, 55 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 1cb35c753dcd..3eed71a2ff2b 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -98,65 +98,79 @@ __rpc_add_timer(struct rpc_wait_queue *queue, struct rpc_task *task)
list_add(&task->u.tk_wait.timer_list, &queue->timer_list.list);
}
-static void rpc_rotate_queue_owner(struct rpc_wait_queue *queue)
-{
- struct list_head *q = &queue->tasks[queue->priority];
- struct rpc_task *task;
-
- if (!list_empty(q)) {
- task = list_first_entry(q, struct rpc_task, u.tk_wait.list);
- if (task->tk_owner == queue->owner)
- list_move_tail(&task->u.tk_wait.list, q);
- }
-}
-
static void rpc_set_waitqueue_priority(struct rpc_wait_queue *queue, int priority)
{
if (queue->priority != priority) {
- /* Fairness: rotate the list when changing priority */
- rpc_rotate_queue_owner(queue);
queue->priority = priority;
+ queue->nr = 1U << priority;
}
}
-static void rpc_set_waitqueue_owner(struct rpc_wait_queue *queue, pid_t pid)
-{
- queue->owner = pid;
- queue->nr = RPC_BATCH_COUNT;
-}
-
static void rpc_reset_waitqueue_priority(struct rpc_wait_queue *queue)
{
rpc_set_waitqueue_priority(queue, queue->maxpriority);
- rpc_set_waitqueue_owner(queue, 0);
}
/*
- * Add new request to a priority queue.
+ * Add a request to a queue list
*/
-static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue,
- struct rpc_task *task,
- unsigned char queue_priority)
+static void
+__rpc_list_enqueue_task(struct list_head *q, struct rpc_task *task)
{
- struct list_head *q;
struct rpc_task *t;
- INIT_LIST_HEAD(&task->u.tk_wait.links);
- if (unlikely(queue_priority > queue->maxpriority))
- queue_priority = queue->maxpriority;
- if (queue_priority > queue->priority)
- rpc_set_waitqueue_priority(queue, queue_priority);
- q = &queue->tasks[queue_priority];
list_for_each_entry(t, q, u.tk_wait.list) {
if (t->tk_owner == task->tk_owner) {
- list_add_tail(&task->u.tk_wait.list, &t->u.tk_wait.links);
+ list_add_tail(&task->u.tk_wait.links,
+ &t->u.tk_wait.links);
+ /* Cache the queue head in task->u.tk_wait.list */
+ task->u.tk_wait.list.next = q;
+ task->u.tk_wait.list.prev = NULL;
return;
}
}
+ INIT_LIST_HEAD(&task->u.tk_wait.links);
list_add_tail(&task->u.tk_wait.list, q);
}
/*
+ * Remove request from a queue list
+ */
+static void
+__rpc_list_dequeue_task(struct rpc_task *task)
+{
+ struct list_head *q;
+ struct rpc_task *t;
+
+ if (task->u.tk_wait.list.prev == NULL) {
+ list_del(&task->u.tk_wait.links);
+ return;
+ }
+ if (!list_empty(&task->u.tk_wait.links)) {
+ t = list_first_entry(&task->u.tk_wait.links,
+ struct rpc_task,
+ u.tk_wait.links);
+ /* Assume __rpc_list_enqueue_task() cached the queue head */
+ q = t->u.tk_wait.list.next;
+ list_add_tail(&t->u.tk_wait.list, q);
+ list_del(&task->u.tk_wait.links);
+ }
+ list_del(&task->u.tk_wait.list);
+}
+
+/*
+ * Add new request to a priority queue.
+ */
+static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue,
+ struct rpc_task *task,
+ unsigned char queue_priority)
+{
+ if (unlikely(queue_priority > queue->maxpriority))
+ queue_priority = queue->maxpriority;
+ __rpc_list_enqueue_task(&queue->tasks[queue_priority], task);
+}
+
+/*
* Add new request to wait queue.
*
* Swapper tasks always get inserted at the head of the queue.
@@ -193,13 +207,7 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue,
*/
static void __rpc_remove_wait_queue_priority(struct rpc_task *task)
{
- struct rpc_task *t;
-
- if (!list_empty(&task->u.tk_wait.links)) {
- t = list_entry(task->u.tk_wait.links.next, struct rpc_task, u.tk_wait.list);
- list_move(&t->u.tk_wait.list, &task->u.tk_wait.list);
- list_splice_init(&task->u.tk_wait.links, &t->u.tk_wait.links);
- }
+ __rpc_list_dequeue_task(task);
}
/*
@@ -211,7 +219,8 @@ static void __rpc_remove_wait_queue(struct rpc_wait_queue *queue, struct rpc_tas
__rpc_disable_timer(queue, task);
if (RPC_IS_PRIORITY(queue))
__rpc_remove_wait_queue_priority(task);
- list_del(&task->u.tk_wait.list);
+ else
+ list_del(&task->u.tk_wait.list);
queue->qlen--;
dprintk("RPC: %5u removed from queue %p \"%s\"\n",
task->tk_pid, queue, rpc_qname(queue));
@@ -467,17 +476,9 @@ static struct rpc_task *__rpc_find_next_queued_priority(struct rpc_wait_queue *q
* Service a batch of tasks from a single owner.
*/
q = &queue->tasks[queue->priority];
- if (!list_empty(q)) {
- task = list_entry(q->next, struct rpc_task, u.tk_wait.list);
- if (queue->owner == task->tk_owner) {
- if (--queue->nr)
- goto out;
- list_move_tail(&task->u.tk_wait.list, q);
- }
- /*
- * Check if we need to switch queues.
- */
- goto new_owner;
+ if (!list_empty(q) && --queue->nr) {
+ task = list_first_entry(q, struct rpc_task, u.tk_wait.list);
+ goto out;
}
/*
@@ -489,7 +490,7 @@ static struct rpc_task *__rpc_find_next_queued_priority(struct rpc_wait_queue *q
else
q = q - 1;
if (!list_empty(q)) {
- task = list_entry(q->next, struct rpc_task, u.tk_wait.list);
+ task = list_first_entry(q, struct rpc_task, u.tk_wait.list);
goto new_queue;
}
} while (q != &queue->tasks[queue->priority]);
@@ -499,8 +500,6 @@ static struct rpc_task *__rpc_find_next_queued_priority(struct rpc_wait_queue *q
new_queue:
rpc_set_waitqueue_priority(queue, (unsigned int)(q - &queue->tasks[0]));
-new_owner:
- rpc_set_waitqueue_owner(queue, task->tk_owner);
out:
return task;
}