From: Sasha Levin Date: Sat, 9 Jan 2021 15:00:44 +0000 (-0500) Subject: Fixes for 4.9 X-Git-Tag: v4.4.251~54 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fba7ad3827dfecefa63091772fce1c75c93546df;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.9 Signed-off-by: Sasha Levin --- diff --git a/queue-4.9/depmod-handle-the-case-of-sbin-depmod-without-sbin-i.patch b/queue-4.9/depmod-handle-the-case-of-sbin-depmod-without-sbin-i.patch new file mode 100644 index 00000000000..09b7974e6e0 --- /dev/null +++ b/queue-4.9/depmod-handle-the-case-of-sbin-depmod-without-sbin-i.patch @@ -0,0 +1,40 @@ +From 15cfdd413b6733adf726310d3f46c6fd88299d9d 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 baedaef53ca05..b0cb89e73bc56 100755 +--- a/scripts/depmod.sh ++++ b/scripts/depmod.sh +@@ -14,6 +14,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-4.9/lib-genalloc-fix-the-overflow-when-size-is-too-big.patch b/queue-4.9/lib-genalloc-fix-the-overflow-when-size-is-too-big.patch new file mode 100644 index 00000000000..37b74befeed --- /dev/null +++ b/queue-4.9/lib-genalloc-fix-the-overflow-when-size-is-too-big.patch @@ -0,0 +1,131 @@ +From 1b3a80fefcbd277dbb2ffa76e5d2c4fc245d08fe 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 7e85d1e37a6ea..0b8ee173cf3a6 100644 +--- a/lib/genalloc.c ++++ b/lib/genalloc.c +@@ -83,14 +83,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; +@@ -118,14 +118,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; +@@ -184,8 +185,8 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy + size_t size, int nid) + { + 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); +@@ -293,7 +294,7 @@ unsigned long gen_pool_alloc_algo(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()); +@@ -376,7 +377,7 @@ void gen_pool_free(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()); +@@ -638,7 +639,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-4.9/series b/queue-4.9/series new file mode 100644 index 00000000000..82117109fd1 --- /dev/null +++ b/queue-4.9/series @@ -0,0 +1,3 @@ +workqueue-kick-a-worker-based-on-the-actual-activati.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-4.9/workqueue-kick-a-worker-based-on-the-actual-activati.patch b/queue-4.9/workqueue-kick-a-worker-based-on-the-actual-activati.patch new file mode 100644 index 00000000000..77c2d2b5e30 --- /dev/null +++ b/queue-4.9/workqueue-kick-a-worker-based-on-the-actual-activati.patch @@ -0,0 +1,69 @@ +From 51cf85b89d4880986945b458ec542d5f5674a1cd 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 00c295d3104bb..205c3131f8b05 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -3448,17 +3448,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 +