From: Sasha Levin Date: Fri, 7 Feb 2020 16:10:37 +0000 (-0500) Subject: fixes for 4.9 X-Git-Tag: v4.19.103~83 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3fb3872f8973462c6b74f85c26b1a0422efbee9b;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 4.9 Signed-off-by: Sasha Levin --- diff --git a/queue-4.9/padata-remove-broken-queue-flushing.patch b/queue-4.9/padata-remove-broken-queue-flushing.patch new file mode 100644 index 00000000000..75d7ca633c4 --- /dev/null +++ b/queue-4.9/padata-remove-broken-queue-flushing.patch @@ -0,0 +1,144 @@ +From 922e632cbb5d408ccacb45addde1285f360bdeb2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Nov 2019 13:17:31 +0800 +Subject: padata: Remove broken queue flushing + +From: Herbert Xu + +[ Upstream commit 07928d9bfc81640bab36f5190e8725894d93b659 ] + +The function padata_flush_queues is fundamentally broken because +it cannot force padata users to complete the request that is +underway. IOW padata has to passively wait for the completion +of any outstanding work. + +As it stands flushing is used in two places. Its use in padata_stop +is simply unnecessary because nothing depends on the queues to +be flushed afterwards. + +The other use in padata_replace is more substantial as we depend +on it to free the old pd structure. This patch instead uses the +pd->refcnt to dynamically free the pd structure once all requests +are complete. + +Fixes: 2b73b07ab8a4 ("padata: Flush the padata queues actively") +Cc: +Signed-off-by: Herbert Xu +Reviewed-by: Daniel Jordan +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + kernel/padata.c | 46 ++++++++++++---------------------------------- + 1 file changed, 12 insertions(+), 34 deletions(-) + +diff --git a/kernel/padata.c b/kernel/padata.c +index 63449fc584daf..9ba611b42abac 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -34,6 +34,8 @@ + + #define MAX_OBJ_NUM 1000 + ++static void padata_free_pd(struct parallel_data *pd); ++ + static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index) + { + int cpu, target_cpu; +@@ -301,6 +303,7 @@ static void padata_serial_worker(struct work_struct *serial_work) + struct padata_serial_queue *squeue; + struct parallel_data *pd; + LIST_HEAD(local_list); ++ int cnt; + + local_bh_disable(); + squeue = container_of(serial_work, struct padata_serial_queue, work); +@@ -310,6 +313,8 @@ static void padata_serial_worker(struct work_struct *serial_work) + list_replace_init(&squeue->serial.list, &local_list); + spin_unlock(&squeue->serial.lock); + ++ cnt = 0; ++ + while (!list_empty(&local_list)) { + struct padata_priv *padata; + +@@ -319,9 +324,12 @@ static void padata_serial_worker(struct work_struct *serial_work) + list_del_init(&padata->list); + + padata->serial(padata); +- atomic_dec(&pd->refcnt); ++ cnt++; + } + local_bh_enable(); ++ ++ if (atomic_sub_and_test(cnt, &pd->refcnt)) ++ padata_free_pd(pd); + } + + /** +@@ -444,8 +452,7 @@ static struct parallel_data *padata_alloc_pd(struct padata_instance *pinst, + setup_timer(&pd->timer, padata_reorder_timer, (unsigned long)pd); + atomic_set(&pd->seq_nr, -1); + atomic_set(&pd->reorder_objects, 0); +- atomic_set(&pd->refcnt, 0); +- pd->pinst = pinst; ++ atomic_set(&pd->refcnt, 1); + spin_lock_init(&pd->lock); + + return pd; +@@ -469,31 +476,6 @@ static void padata_free_pd(struct parallel_data *pd) + kfree(pd); + } + +-/* Flush all objects out of the padata queues. */ +-static void padata_flush_queues(struct parallel_data *pd) +-{ +- int cpu; +- struct padata_parallel_queue *pqueue; +- struct padata_serial_queue *squeue; +- +- for_each_cpu(cpu, pd->cpumask.pcpu) { +- pqueue = per_cpu_ptr(pd->pqueue, cpu); +- flush_work(&pqueue->work); +- } +- +- del_timer_sync(&pd->timer); +- +- if (atomic_read(&pd->reorder_objects)) +- padata_reorder(pd); +- +- for_each_cpu(cpu, pd->cpumask.cbcpu) { +- squeue = per_cpu_ptr(pd->squeue, cpu); +- flush_work(&squeue->work); +- } +- +- BUG_ON(atomic_read(&pd->refcnt) != 0); +-} +- + static void __padata_start(struct padata_instance *pinst) + { + pinst->flags |= PADATA_INIT; +@@ -507,10 +489,6 @@ static void __padata_stop(struct padata_instance *pinst) + pinst->flags &= ~PADATA_INIT; + + synchronize_rcu(); +- +- get_online_cpus(); +- padata_flush_queues(pinst->pd); +- put_online_cpus(); + } + + /* Replace the internal control structure with a new one. */ +@@ -531,8 +509,8 @@ static void padata_replace(struct padata_instance *pinst, + if (!cpumask_equal(pd_old->cpumask.cbcpu, pd_new->cpumask.cbcpu)) + notification_mask |= PADATA_CPU_SERIAL; + +- padata_flush_queues(pd_old); +- padata_free_pd(pd_old); ++ if (atomic_dec_and_test(&pd_old->refcnt)) ++ padata_free_pd(pd_old); + + if (notification_mask) + blocking_notifier_call_chain(&pinst->cpumask_change_notifier, +-- +2.20.1 + diff --git a/queue-4.9/series b/queue-4.9/series index fd53c0f1ea5..d2412d77bf2 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -33,3 +33,4 @@ scsi-qla2xxx-fix-mtcp-dump-collection-failure.patch power-supply-ltc2941-battery-gauge-fix-use-after-free.patch of-add-of_dma_default_coherent-select-it-on-powerpc.patch dm-space-map-common-fix-to-ensure-new-block-isn-t-already-in-use.patch +padata-remove-broken-queue-flushing.patch