Even after we fix the use of a non raw lock in free_ioctx_users() we still get another follow on splat. This one looks as follows: BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:905 in_atomic(): 1, irqs_disabled(): 0, pid: 14, name: rcuc/0 Preemption disabled at:[<ffffffff810ada55>] rcu_cpu_kthread+0x295/0x6f0 CPU: 0 PID: 14 Comm: rcuc/0 Not tainted 3.14.31-rt28-WR7.0.0.0_ovp+ #5 Hardware name: Intel Corporation S2600CP/S2600CP, BIOS SE5C600.86B.02.01.0002.082220131453 08/22/2013 000000000000c3c0 ffff880fb393fd28 ffffffff819ffe6b 0000000000000000 ffff880fb393fd40 ffffffff8107b6cb ffff880ffe60c3c0 ffff880fb393fd58 ffffffff81a077c0 ffff880ffe60c3c0 ffff880fb393fd98 ffffffff81066f05 Call Trace: [<ffffffff819ffe6b>] dump_stack+0x4e/0x7a [<ffffffff8107b6cb>] __might_sleep+0xdb/0x150 [<ffffffff81a077c0>] rt_spin_lock+0x20/0x50 [<ffffffff81066f05>] queue_work_on+0x65/0x110 [<ffffffff811c714b>] free_ioctx_reqs+0x5b/0x60 [<ffffffff813ff06b>] percpu_ref_kill_rcu+0x11b/0x120 [<ffffffff810ada55>] rcu_cpu_kthread+0x295/0x6f0 [<ffffffff81076c7d>] smpboot_thread_fn+0x17d/0x2b0 [<ffffffff81a05220>] ? schedule+0x30/0xa0 [<ffffffff81076b00>] ? SyS_setgroups+0x170/0x170 [<ffffffff8106f3f4>] kthread+0xc4/0xe0 [<ffffffff8106f330>] ? flush_kthread_worker+0x90/0x90 [<ffffffff81a088ec>] ret_from_fork+0x7c/0xb0 [<ffffffff8106f330>] ? flush_kthread_worker+0x90/0x90 This is caused by schedule_work() being called from free_ioctx_reqs(), and the underlying reason is the same, that this release fcn... * Note that @release must not sleep - it may potentially be called from RCU * callback context by percpu_ref_kill(). and the sleep is spin_lock_irqsave(&lv->lock, lv->flags) inside queue_work_on(). We can fix this up by using the callback version percpu_ref_kill and register the callback to do the schedule_work(). With this in place a reboot doesn't splat during aio garbage collection. Signed-off-by: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx> --- fs/aio.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/aio.c b/fs/aio.c index d806f7223822..db1ce6d73cc7 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -524,6 +524,11 @@ static void free_ioctx_reqs(struct percpu_ref *ref) /* At this point we know that there are no any in-flight requests */ if (ctx->requests_done) complete(ctx->requests_done); +} + +static void free_ioctx_reqs_callback(struct percpu_ref *ref) +{ + struct kioctx *ctx = container_of(ref, struct kioctx, reqs); INIT_WORK(&ctx->free_work, free_ioctx); schedule_work(&ctx->free_work); @@ -558,7 +563,7 @@ static void free_ioctx_users(struct percpu_ref *ref) spin_unlock_irq(&ctx->ctx_lock); #endif - percpu_ref_kill(&ctx->reqs); + percpu_ref_kill_and_confirm(&ctx->reqs, free_ioctx_reqs_callback); percpu_ref_put(&ctx->reqs); } -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html