From 2c7333c24e84ae318ce2b1df3bcf1a16466eed27 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 9 Jan 2021 10:00:43 -0500 Subject: [PATCH] Fixes for 5.4 Signed-off-by: Sasha Levin --- ...e-case-of-sbin-depmod-without-sbin-i.patch | 40 ++++++ ...ix-the-overflow-when-size-is-too-big.patch | 131 ++++++++++++++++++ ...set-the-rqf_preempt-flag-for-sense-r.patch | 88 ++++++++++++ ...ort_spi-set-rqf_pm-for-domain-valida.patch | 108 +++++++++++++++ ...s-fix-wrong-print-message-in-dev_err.patch | 38 +++++ ...ure-ufs-device-is-in-powerdown-mode-.patch | 78 +++++++++++ queue-5.4/series | 7 + ...-worker-based-on-the-actual-activati.patch | 69 +++++++++ 8 files changed, 559 insertions(+) create mode 100644 queue-5.4/depmod-handle-the-case-of-sbin-depmod-without-sbin-i.patch create mode 100644 queue-5.4/lib-genalloc-fix-the-overflow-when-size-is-too-big.patch create mode 100644 queue-5.4/scsi-ide-do-not-set-the-rqf_preempt-flag-for-sense-r.patch create mode 100644 queue-5.4/scsi-scsi_transport_spi-set-rqf_pm-for-domain-valida.patch create mode 100644 queue-5.4/scsi-ufs-fix-wrong-print-message-in-dev_err.patch create mode 100644 queue-5.4/scsi-ufs-pci-ensure-ufs-device-is-in-powerdown-mode-.patch create mode 100644 queue-5.4/series create mode 100644 queue-5.4/workqueue-kick-a-worker-based-on-the-actual-activati.patch diff --git a/queue-5.4/depmod-handle-the-case-of-sbin-depmod-without-sbin-i.patch b/queue-5.4/depmod-handle-the-case-of-sbin-depmod-without-sbin-i.patch new file mode 100644 index 00000000000..f738d75a3fa --- /dev/null +++ b/queue-5.4/depmod-handle-the-case-of-sbin-depmod-without-sbin-i.patch @@ -0,0 +1,40 @@ +From a2ef73e7c77ec050b6306b5c56d7de511338ffc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Dec 2020 11:40:22 -0800 +Subject: depmod: handle the case of /sbin/depmod without /sbin in PATH + +From: Linus Torvalds + +[ Upstream commit cedd1862be7e666be87ec824dabc6a2b05618f36 ] + +Commit 436e980e2ed5 ("kbuild: don't hardcode depmod path") stopped +hard-coding the path of depmod, but in the process caused trouble for +distributions that had that /sbin location, but didn't have it in the +PATH (generally because /sbin is limited to the super-user path). + +Work around it for now by just adding /sbin to the end of PATH in the +depmod.sh script. + +Reported-and-tested-by: Sedat Dilek +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + scripts/depmod.sh | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/scripts/depmod.sh b/scripts/depmod.sh +index e083bcae343f3..3643b4f896ede 100755 +--- a/scripts/depmod.sh ++++ b/scripts/depmod.sh +@@ -15,6 +15,8 @@ if ! test -r System.map ; then + exit 0 + fi + ++# legacy behavior: "depmod" in /sbin, no /sbin in PATH ++PATH="$PATH:/sbin" + if [ -z $(command -v $DEPMOD) ]; then + echo "Warning: 'make modules_install' requires $DEPMOD. Please install it." >&2 + echo "This is probably in the kmod package." >&2 +-- +2.27.0 + diff --git a/queue-5.4/lib-genalloc-fix-the-overflow-when-size-is-too-big.patch b/queue-5.4/lib-genalloc-fix-the-overflow-when-size-is-too-big.patch new file mode 100644 index 00000000000..85fad7dd0c5 --- /dev/null +++ b/queue-5.4/lib-genalloc-fix-the-overflow-when-size-is-too-big.patch @@ -0,0 +1,131 @@ +From 700eb19e285e6f9411cffa72dd17807e7a9c6d4f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Dec 2020 15:14:58 -0800 +Subject: lib/genalloc: fix the overflow when size is too big + +From: Huang Shijie + +[ Upstream commit 36845663843fc59c5d794e3dc0641472e3e572da ] + +Some graphic card has very big memory on chip, such as 32G bytes. + +In the following case, it will cause overflow: + + pool = gen_pool_create(PAGE_SHIFT, NUMA_NO_NODE); + ret = gen_pool_add(pool, 0x1000000, SZ_32G, NUMA_NO_NODE); + + va = gen_pool_alloc(pool, SZ_4G); + +The overflow occurs in gen_pool_alloc_algo_owner(): + + .... + size = nbits << order; + .... + +The @nbits is "int" type, so it will overflow. +Then the gen_pool_avail() will return the wrong value. + +This patch converts some "int" to "unsigned long", and +changes the compare code in while. + +Link: https://lkml.kernel.org/r/20201229060657.3389-1-sjhuang@iluvatar.ai +Signed-off-by: Huang Shijie +Reported-by: Shi Jiasheng +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + lib/genalloc.c | 25 +++++++++++++------------ + 1 file changed, 13 insertions(+), 12 deletions(-) + +diff --git a/lib/genalloc.c b/lib/genalloc.c +index 9fc31292cfa1d..80d10d02cf388 100644 +--- a/lib/genalloc.c ++++ b/lib/genalloc.c +@@ -81,14 +81,14 @@ static int clear_bits_ll(unsigned long *addr, unsigned long mask_to_clear) + * users set the same bit, one user will return remain bits, otherwise + * return 0. + */ +-static int bitmap_set_ll(unsigned long *map, int start, int nr) ++static int bitmap_set_ll(unsigned long *map, unsigned long start, unsigned long nr) + { + unsigned long *p = map + BIT_WORD(start); +- const int size = start + nr; ++ const unsigned long size = start + nr; + int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); + unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); + +- while (nr - bits_to_set >= 0) { ++ while (nr >= bits_to_set) { + if (set_bits_ll(p, mask_to_set)) + return nr; + nr -= bits_to_set; +@@ -116,14 +116,15 @@ static int bitmap_set_ll(unsigned long *map, int start, int nr) + * users clear the same bit, one user will return remain bits, + * otherwise return 0. + */ +-static int bitmap_clear_ll(unsigned long *map, int start, int nr) ++static unsigned long ++bitmap_clear_ll(unsigned long *map, unsigned long start, unsigned long nr) + { + unsigned long *p = map + BIT_WORD(start); +- const int size = start + nr; ++ const unsigned long size = start + nr; + int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG); + unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start); + +- while (nr - bits_to_clear >= 0) { ++ while (nr >= bits_to_clear) { + if (clear_bits_ll(p, mask_to_clear)) + return nr; + nr -= bits_to_clear; +@@ -183,8 +184,8 @@ int gen_pool_add_owner(struct gen_pool *pool, unsigned long virt, phys_addr_t ph + size_t size, int nid, void *owner) + { + struct gen_pool_chunk *chunk; +- int nbits = size >> pool->min_alloc_order; +- int nbytes = sizeof(struct gen_pool_chunk) + ++ unsigned long nbits = size >> pool->min_alloc_order; ++ unsigned long nbytes = sizeof(struct gen_pool_chunk) + + BITS_TO_LONGS(nbits) * sizeof(long); + + chunk = vzalloc_node(nbytes, nid); +@@ -242,7 +243,7 @@ void gen_pool_destroy(struct gen_pool *pool) + struct list_head *_chunk, *_next_chunk; + struct gen_pool_chunk *chunk; + int order = pool->min_alloc_order; +- int bit, end_bit; ++ unsigned long bit, end_bit; + + list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { + chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); +@@ -278,7 +279,7 @@ unsigned long gen_pool_alloc_algo_owner(struct gen_pool *pool, size_t size, + struct gen_pool_chunk *chunk; + unsigned long addr = 0; + int order = pool->min_alloc_order; +- int nbits, start_bit, end_bit, remain; ++ unsigned long nbits, start_bit, end_bit, remain; + + #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG + BUG_ON(in_nmi()); +@@ -487,7 +488,7 @@ void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr, size_t size, + { + struct gen_pool_chunk *chunk; + int order = pool->min_alloc_order; +- int start_bit, nbits, remain; ++ unsigned long start_bit, nbits, remain; + + #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG + BUG_ON(in_nmi()); +@@ -754,7 +755,7 @@ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, + index = bitmap_find_next_zero_area(map, size, start, nr, 0); + + while (index < size) { +- int next_bit = find_next_bit(map, size, index + nr); ++ unsigned long next_bit = find_next_bit(map, size, index + nr); + if ((next_bit - index) < len) { + len = next_bit - index; + start_bit = index; +-- +2.27.0 + diff --git a/queue-5.4/scsi-ide-do-not-set-the-rqf_preempt-flag-for-sense-r.patch b/queue-5.4/scsi-ide-do-not-set-the-rqf_preempt-flag-for-sense-r.patch new file mode 100644 index 00000000000..288ef1ec1a4 --- /dev/null +++ b/queue-5.4/scsi-ide-do-not-set-the-rqf_preempt-flag-for-sense-r.patch @@ -0,0 +1,88 @@ +From 7ee283bc4eece6d6c673920542233ac3fc886fc3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Dec 2020 21:29:46 -0800 +Subject: scsi: ide: Do not set the RQF_PREEMPT flag for sense requests + +From: Bart Van Assche + +[ Upstream commit 96d86e6a80a3ab9aff81d12f9f1f2a0da2917d38 ] + +RQF_PREEMPT is used for two different purposes in the legacy IDE code: + + 1. To mark power management requests. + + 2. To mark requests that should preempt another request. An (old) + explanation of that feature is as follows: "The IDE driver in the Linux + kernel normally uses a series of busywait delays during its + initialization. When the driver executes these busywaits, the kernel + does nothing for the duration of the wait. The time spent in these + waits could be used for other initialization activities, if they could + be run concurrently with these waits. + + More specifically, busywait-style delays such as udelay() in module + init functions inhibit kernel preemption because the Big Kernel Lock is + held, while yielding APIs such as schedule_timeout() allow + preemption. This is true because the kernel handles the BKL specially + and releases and reacquires it across reschedules allowed by the + current thread. + + This IDE-preempt specification requires that the driver eliminate these + busywaits and replace them with a mechanism that allows other work to + proceed while the IDE driver is initializing." + +Since I haven't found an implementation of (2), do not set the PREEMPT flag +for sense requests. This patch causes sense requests to be postponed while +a drive is suspended instead of being submitted to ide_queue_rq(). + +If it would ever be necessary to restore the IDE PREEMPT functionality, +that can be done by introducing a new flag in struct ide_request. + +Link: https://lore.kernel.org/r/20201209052951.16136-4-bvanassche@acm.org +Cc: David S. Miller +Cc: Alan Stern +Cc: Can Guo +Cc: Stanley Chu +Cc: Ming Lei +Cc: Rafael J. Wysocki +Reviewed-by: Christoph Hellwig +Reviewed-by: Hannes Reinecke +Reviewed-by: Jens Axboe +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ide/ide-atapi.c | 1 - + drivers/ide/ide-io.c | 5 ----- + 2 files changed, 6 deletions(-) + +diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c +index 80bc3bf82f4d7..775fd34132abb 100644 +--- a/drivers/ide/ide-atapi.c ++++ b/drivers/ide/ide-atapi.c +@@ -223,7 +223,6 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) + sense_rq->rq_disk = rq->rq_disk; + sense_rq->cmd_flags = REQ_OP_DRV_IN; + ide_req(sense_rq)->type = ATA_PRIV_SENSE; +- sense_rq->rq_flags |= RQF_PREEMPT; + + req->cmd[0] = GPCMD_REQUEST_SENSE; + req->cmd[4] = cmd_len; +diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c +index b137f27a34d58..b32a013d827a0 100644 +--- a/drivers/ide/ide-io.c ++++ b/drivers/ide/ide-io.c +@@ -512,11 +512,6 @@ repeat: + * above to return us whatever is in the queue. Since we call + * ide_do_request() ourselves, we end up taking requests while + * the queue is blocked... +- * +- * We let requests forced at head of queue with ide-preempt +- * though. I hope that doesn't happen too much, hopefully not +- * unless the subdriver triggers such a thing in its own PM +- * state machine. + */ + if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && + ata_pm_request(rq) == 0 && +-- +2.27.0 + diff --git a/queue-5.4/scsi-scsi_transport_spi-set-rqf_pm-for-domain-valida.patch b/queue-5.4/scsi-scsi_transport_spi-set-rqf_pm-for-domain-valida.patch new file mode 100644 index 00000000000..fc6f7352cb8 --- /dev/null +++ b/queue-5.4/scsi-scsi_transport_spi-set-rqf_pm-for-domain-valida.patch @@ -0,0 +1,108 @@ +From 3d7dcf5d8e0f97f57e7e2fe29e5200601af681fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Dec 2020 21:29:48 -0800 +Subject: scsi: scsi_transport_spi: Set RQF_PM for domain validation commands + +From: Bart Van Assche + +[ Upstream commit cfefd9f8240a7b9fdd96fcd54cb029870b6d8d88 ] + +Disable runtime power management during domain validation. Since a later +patch removes RQF_PREEMPT, set RQF_PM for domain validation commands such +that these are executed in the quiesced SCSI device state. + +Link: https://lore.kernel.org/r/20201209052951.16136-6-bvanassche@acm.org +Cc: Alan Stern +Cc: James Bottomley +Cc: Woody Suwalski +Cc: Can Guo +Cc: Stanley Chu +Cc: Ming Lei +Cc: Rafael J. Wysocki +Cc: Stan Johnson +Reviewed-by: Christoph Hellwig +Reviewed-by: Jens Axboe +Reviewed-by: Hannes Reinecke +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_transport_spi.c | 27 +++++++++++++++++++-------- + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c +index f3d5b1bbd5aa7..c37dd15d16d24 100644 +--- a/drivers/scsi/scsi_transport_spi.c ++++ b/drivers/scsi/scsi_transport_spi.c +@@ -117,12 +117,16 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd, + sshdr = &sshdr_tmp; + + for(i = 0; i < DV_RETRIES; i++) { ++ /* ++ * The purpose of the RQF_PM flag below is to bypass the ++ * SDEV_QUIESCE state. ++ */ + result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense, + sshdr, DV_TIMEOUT, /* retries */ 1, + REQ_FAILFAST_DEV | + REQ_FAILFAST_TRANSPORT | + REQ_FAILFAST_DRIVER, +- 0, NULL); ++ RQF_PM, NULL); + if (driver_byte(result) != DRIVER_SENSE || + sshdr->sense_key != UNIT_ATTENTION) + break; +@@ -1005,23 +1009,26 @@ spi_dv_device(struct scsi_device *sdev) + */ + lock_system_sleep(); + ++ if (scsi_autopm_get_device(sdev)) ++ goto unlock_system_sleep; ++ + if (unlikely(spi_dv_in_progress(starget))) +- goto unlock; ++ goto put_autopm; + + if (unlikely(scsi_device_get(sdev))) +- goto unlock; ++ goto put_autopm; + + spi_dv_in_progress(starget) = 1; + + buffer = kzalloc(len, GFP_KERNEL); + + if (unlikely(!buffer)) +- goto out_put; ++ goto put_sdev; + + /* We need to verify that the actual device will quiesce; the + * later target quiesce is just a nice to have */ + if (unlikely(scsi_device_quiesce(sdev))) +- goto out_free; ++ goto free_buffer; + + scsi_target_quiesce(starget); + +@@ -1041,12 +1048,16 @@ spi_dv_device(struct scsi_device *sdev) + + spi_initial_dv(starget) = 1; + +- out_free: ++free_buffer: + kfree(buffer); +- out_put: ++ ++put_sdev: + spi_dv_in_progress(starget) = 0; + scsi_device_put(sdev); +-unlock: ++put_autopm: ++ scsi_autopm_put_device(sdev); ++ ++unlock_system_sleep: + unlock_system_sleep(); + } + EXPORT_SYMBOL(spi_dv_device); +-- +2.27.0 + diff --git a/queue-5.4/scsi-ufs-fix-wrong-print-message-in-dev_err.patch b/queue-5.4/scsi-ufs-fix-wrong-print-message-in-dev_err.patch new file mode 100644 index 00000000000..6ad654e754b --- /dev/null +++ b/queue-5.4/scsi-ufs-fix-wrong-print-message-in-dev_err.patch @@ -0,0 +1,38 @@ +From 9cd380aee9167fdd00e6b1fa94242e08c1012e5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Dec 2020 20:01:37 +0100 +Subject: scsi: ufs: Fix wrong print message in dev_err() + +From: Bean Huo + +[ Upstream commit 1fa0570002e3f66db9b58c32c60de4183b857a19 ] + +Change dev_err() print message from "dme-reset" to "dme_enable" in function +ufshcd_dme_enable(). + +Link: https://lore.kernel.org/r/20201207190137.6858-3-huobean@gmail.com +Acked-by: Alim Akhtar +Acked-by: Avri Altman +Signed-off-by: Bean Huo +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ufs/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index 675e16e61ebdd..b888117f4ecd3 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -3593,7 +3593,7 @@ static int ufshcd_dme_enable(struct ufs_hba *hba) + ret = ufshcd_send_uic_cmd(hba, &uic_cmd); + if (ret) + dev_err(hba->dev, +- "dme-reset: error code %d\n", ret); ++ "dme-enable: error code %d\n", ret); + + return ret; + } +-- +2.27.0 + diff --git a/queue-5.4/scsi-ufs-pci-ensure-ufs-device-is-in-powerdown-mode-.patch b/queue-5.4/scsi-ufs-pci-ensure-ufs-device-is-in-powerdown-mode-.patch new file mode 100644 index 00000000000..fb08436295e --- /dev/null +++ b/queue-5.4/scsi-ufs-pci-ensure-ufs-device-is-in-powerdown-mode-.patch @@ -0,0 +1,78 @@ +From 3b22fb3b57f320171a0e88280db69b52f7b5c57e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Dec 2020 10:31:18 +0200 +Subject: scsi: ufs-pci: Ensure UFS device is in PowerDown mode for + suspend-to-disk ->poweroff() + +From: Adrian Hunter + +[ Upstream commit af423534d2de86cd0db729a5ac41f056ca8717de ] + +The expectation for suspend-to-disk is that devices will be powered-off, so +the UFS device should be put in PowerDown mode. If spm_lvl is not 5, then +that will not happen. Change the pm callbacks to force spm_lvl 5 for +suspend-to-disk poweroff. + +Link: https://lore.kernel.org/r/20201207083120.26732-3-adrian.hunter@intel.com +Signed-off-by: Adrian Hunter +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ufs/ufshcd-pci.c | 34 ++++++++++++++++++++++++++++++++-- + 1 file changed, 32 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c +index 3b19de3ae9a30..e4ba2445ff56f 100644 +--- a/drivers/scsi/ufs/ufshcd-pci.c ++++ b/drivers/scsi/ufs/ufshcd-pci.c +@@ -96,6 +96,30 @@ static int ufshcd_pci_resume(struct device *dev) + { + return ufshcd_system_resume(dev_get_drvdata(dev)); + } ++ ++/** ++ * ufshcd_pci_poweroff - suspend-to-disk poweroff function ++ * @dev: pointer to PCI device handle ++ * ++ * Returns 0 if successful ++ * Returns non-zero otherwise ++ */ ++static int ufshcd_pci_poweroff(struct device *dev) ++{ ++ struct ufs_hba *hba = dev_get_drvdata(dev); ++ int spm_lvl = hba->spm_lvl; ++ int ret; ++ ++ /* ++ * For poweroff we need to set the UFS device to PowerDown mode. ++ * Force spm_lvl to ensure that. ++ */ ++ hba->spm_lvl = 5; ++ ret = ufshcd_system_suspend(hba); ++ hba->spm_lvl = spm_lvl; ++ return ret; ++} ++ + #endif /* !CONFIG_PM_SLEEP */ + + #ifdef CONFIG_PM +@@ -190,8 +214,14 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + } + + static const struct dev_pm_ops ufshcd_pci_pm_ops = { +- SET_SYSTEM_SLEEP_PM_OPS(ufshcd_pci_suspend, +- ufshcd_pci_resume) ++#ifdef CONFIG_PM_SLEEP ++ .suspend = ufshcd_pci_suspend, ++ .resume = ufshcd_pci_resume, ++ .freeze = ufshcd_pci_suspend, ++ .thaw = ufshcd_pci_resume, ++ .poweroff = ufshcd_pci_poweroff, ++ .restore = ufshcd_pci_resume, ++#endif + SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend, + ufshcd_pci_runtime_resume, + ufshcd_pci_runtime_idle) +-- +2.27.0 + diff --git a/queue-5.4/series b/queue-5.4/series new file mode 100644 index 00000000000..a91ef68f5c4 --- /dev/null +++ b/queue-5.4/series @@ -0,0 +1,7 @@ +workqueue-kick-a-worker-based-on-the-actual-activati.patch +scsi-ufs-fix-wrong-print-message-in-dev_err.patch +scsi-ufs-pci-ensure-ufs-device-is-in-powerdown-mode-.patch +scsi-ide-do-not-set-the-rqf_preempt-flag-for-sense-r.patch +scsi-scsi_transport_spi-set-rqf_pm-for-domain-valida.patch +lib-genalloc-fix-the-overflow-when-size-is-too-big.patch +depmod-handle-the-case-of-sbin-depmod-without-sbin-i.patch diff --git a/queue-5.4/workqueue-kick-a-worker-based-on-the-actual-activati.patch b/queue-5.4/workqueue-kick-a-worker-based-on-the-actual-activati.patch new file mode 100644 index 00000000000..5c176d8ee9d --- /dev/null +++ b/queue-5.4/workqueue-kick-a-worker-based-on-the-actual-activati.patch @@ -0,0 +1,69 @@ +From 069a0db4d8bc8727d3635ac73b273b8cdffb9933 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Nov 2020 14:21:25 +0800 +Subject: workqueue: Kick a worker based on the actual activation of delayed + works + +From: Yunfeng Ye + +[ Upstream commit 01341fbd0d8d4e717fc1231cdffe00343088ce0b ] + +In realtime scenario, We do not want to have interference on the +isolated cpu cores. but when invoking alloc_workqueue() for percpu wq +on the housekeeping cpu, it kick a kworker on the isolated cpu. + + alloc_workqueue + pwq_adjust_max_active + wake_up_worker + +The comment in pwq_adjust_max_active() said: + "Need to kick a worker after thawed or an unbound wq's + max_active is bumped" + +So it is unnecessary to kick a kworker for percpu's wq when invoking +alloc_workqueue(). this patch only kick a worker based on the actual +activation of delayed works. + +Signed-off-by: Yunfeng Ye +Reviewed-by: Lai Jiangshan +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/workqueue.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 4aa268582a225..28e52657e0930 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -3718,17 +3718,24 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq) + * is updated and visible. + */ + if (!freezable || !workqueue_freezing) { ++ bool kick = false; ++ + pwq->max_active = wq->saved_max_active; + + while (!list_empty(&pwq->delayed_works) && +- pwq->nr_active < pwq->max_active) ++ pwq->nr_active < pwq->max_active) { + pwq_activate_first_delayed(pwq); ++ kick = true; ++ } + + /* + * Need to kick a worker after thawed or an unbound wq's +- * max_active is bumped. It's a slow path. Do it always. ++ * max_active is bumped. In realtime scenarios, always kicking a ++ * worker will cause interference on the isolated cpu cores, so ++ * let's kick iff work items were activated. + */ +- wake_up_worker(pwq->pool); ++ if (kick) ++ wake_up_worker(pwq->pool); + } else { + pwq->max_active = 0; + } +-- +2.27.0 + -- 2.47.3