diff options
author | Petr Mladek <pmladek@suse.com> | 2016-10-19 14:07:19 +0200 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-12-14 12:16:11 -0500 |
commit | 6efaf10f163d9a60d1d4b2a049b194a53537ba1b (patch) | |
tree | 24c430ab5e6d794a205bcdfb627fa3ce3422cd38 /drivers/input/sparse-keymap.c | |
parent | 66431b0e8657e2406742105f89175f571340090b (diff) |
IB/rdmavt: Avoid queuing work into a destroyed cq kthread worker
The memory barrier is not enough to protect queuing works into
a destroyed cq kthread. Just imagine the following situation:
CPU1 CPU2
rvt_cq_enter()
worker = cq->rdi->worker;
rvt_cq_exit()
rdi->worker = NULL;
smp_wmb();
kthread_flush_worker(worker);
kthread_stop(worker->task);
kfree(worker);
// nothing queued yet =>
// nothing flushed and
// happily stopped and freed
if (likely(worker)) {
// true => read before CPU2 acted
cq->notify = RVT_CQ_NONE;
cq->triggered++;
kthread_queue_work(worker, &cq->comptask);
BANG: worker has been flushed/stopped/freed in the meantime.
This patch solves this by protecting the critical sections by
rdi->n_cqs_lock. It seems that this lock is not much contended
and looks reasonable for this purpose.
One catch is that rvt_cq_enter() might be called from IRQ context.
Therefore we must always take the lock with IRQs disabled to avoid
a possible deadlock.
Signed-off-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/input/sparse-keymap.c')
0 files changed, 0 insertions, 0 deletions