From 8aae2413b38dbbb4da1f816a673748551ca21c34 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 11 Dec 2015 01:39:46 +0000 Subject: [PATCH] ib_srpt: Convert srpt_ch_list_empty() to RCU This patch avoids that the following warning is reported when unloading the ib_srpt kernel module: WARNING: CPU: 9 PID: 33739 at kernel/sched/core.c:7533 __might_sleep+0x82/0x90() do not call blocking ops when !TASK_RUNNING; state=2 set at [] prepare_to_wait_event+0x63/0x110 Call Trace: [] dump_stack+0x4f/0x74 [] warn_slowpath_common+0x8b/0xd0 [] warn_slowpath_fmt+0x41/0x70 [] __might_sleep+0x82/0x90 [] mutex_lock_nested+0x33/0x380 [] srpt_ch_list_empty+0x2b/0x80 [ib_srpt] [] srpt_release_sport+0xcc/0x2a0 [ib_srpt] [] srpt_release+0x35/0x80 [ib_srpt] [] scst_unregister_target+0x70/0x380 [scst] [] srpt_remove_one+0xb1/0x150 [ib_srpt] [] ib_unregister_client+0xe5/0x190 [ib_core] [] srpt_cleanup_module+0x21/0x2f [ib_srpt] [] SyS_delete_module+0x17b/0x1c0 [] entry_SYSCALL_64_fastpath+0x12/0x6f git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6726 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- srpt/src/ib_srpt.c | 21 ++++++++++++--------- srpt/src/ib_srpt.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 6015f29fa..2d2895335 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -2098,7 +2098,7 @@ static void srpt_free_ch(struct kref *kref) srpt_destroy_ch_ib(ch); - kfree(ch); + kfree_rcu(ch, rcu); } static void srpt_unreg_ch(struct srpt_rdma_ch *ch) @@ -2127,7 +2127,7 @@ static void srpt_unreg_ch(struct srpt_rdma_ch *ch) * after list_del() and before wake_up() has been invoked. */ mutex_lock(&sport->mutex); - list_del(&ch->list); + list_del_rcu(&ch->list); wake_up(&sport->ch_releaseQ); mutex_unlock(&sport->mutex); @@ -2397,7 +2397,8 @@ static struct srpt_nexus *srpt_get_nexus(struct srpt_port *sport, } } if (!nexus && tmp_nexus) { - list_add_tail(&tmp_nexus->entry, &sport->nexus_list); + list_add_tail_rcu(&tmp_nexus->entry, + &sport->nexus_list); swap(nexus, tmp_nexus); } mutex_unlock(&sport->mutex); @@ -2695,7 +2696,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, rsp->rsp_flags = SRP_LOGIN_RSP_MULTICHAN_MAINTAINED; } - list_add_tail(&ch->list, &nexus->ch_list); + list_add_tail_rcu(&ch->list, &nexus->ch_list); ch->thread = thread; if (!sport->enabled) { @@ -3841,11 +3842,11 @@ static bool srpt_ch_list_empty(struct srpt_port *sport) struct srpt_nexus *nexus; bool res = true; - mutex_lock(&sport->mutex); - list_for_each_entry(nexus, &sport->nexus_list, entry) + rcu_read_lock(); + list_for_each_entry_rcu(nexus, &sport->nexus_list, entry) if (!list_empty(&nexus->ch_list)) res = false; - mutex_unlock(&sport->mutex); + rcu_read_unlock(); return res; } @@ -3885,8 +3886,8 @@ static int srpt_release_sport(struct srpt_port *sport) mutex_lock(&sport->mutex); list_for_each_entry_safe(nexus, next_n, &sport->nexus_list, entry) { - list_del(&nexus->entry); - kfree(nexus); + list_del_rcu(&nexus->entry); + kfree_rcu(nexus, rcu); } mutex_unlock(&sport->mutex); @@ -4590,6 +4591,8 @@ out: static void __exit srpt_cleanup_module(void) { + rcu_barrier(); + if (rdma_cm_id) rdma_destroy_id(rdma_cm_id); ib_unregister_client(&srpt_client); diff --git a/srpt/src/ib_srpt.h b/srpt/src/ib_srpt.h index bbe52c011..fdf57791f 100644 --- a/srpt/src/ib_srpt.h +++ b/srpt/src/ib_srpt.h @@ -361,6 +361,7 @@ struct srpt_rdma_ch { }; struct ib_cq *cq; struct kref kref; + struct rcu_head rcu; int rq_size; int max_sge; int max_rsp_size; @@ -397,6 +398,7 @@ struct srpt_rdma_ch { struct srpt_nexus { struct list_head entry; struct list_head ch_list; + struct rcu_head rcu; u8 i_port_id[16]; u8 t_port_id[16]; };