From: Parthasarathy Bhuvaragan Date: Tue, 2 Feb 2016 09:52:15 +0000 (+0100) Subject: tipc: protect tipc_subscrb_get() with subscriber spin lock X-Git-Tag: v4.9.8~2476^2~323^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f3ad288c56d21e3b8ec77e13ab9aa06dbbfa3577;p=platform%2Fkernel%2Flinux-rpi3.git tipc: protect tipc_subscrb_get() with subscriber spin lock Until now, during subscription creation the mod_time() & tipc_subscrb_get() are called after releasing the subscriber spin lock. In a SMP system when performing a subscription creation, if the subscription timeout occurs simultaneously (the timer is scheduled to run on another CPU) then the timer thread might decrement the subscribers refcount before the create thread increments the refcount. This can be simulated by creating subscription with timeout=0 and sometimes the timeout occurs before the create request is complete. This leads to the following message: [30.702949] BUG: spinlock bad magic on CPU#1, kworker/u8:3/87 [30.703834] general protection fault: 0000 [#1] SMP [30.704826] CPU: 1 PID: 87 Comm: kworker/u8:3 Not tainted 4.4.0-rc8+ #18 [30.704826] Workqueue: tipc_rcv tipc_recv_work [tipc] [30.704826] task: ffff88003f878600 ti: ffff88003fae0000 task.ti: ffff88003fae0000 [30.704826] RIP: 0010:[] [] spin_dump+0x5c/0xe0 [...] [30.704826] Call Trace: [30.704826] [] spin_bug+0x26/0x30 [30.704826] [] do_raw_spin_lock+0xe5/0x120 [30.704826] [] _raw_spin_lock_bh+0x19/0x20 [30.704826] [] tipc_subscrb_rcv_cb+0x1d0/0x330 [tipc] [30.704826] [] tipc_receive_from_sock+0xc1/0x150 [tipc] [30.704826] [] tipc_recv_work+0x3f/0x80 [tipc] [30.704826] [] process_one_work+0x149/0x3c0 [30.704826] [] worker_thread+0x66/0x460 [30.704826] [] ? process_one_work+0x3c0/0x3c0 [30.704826] [] ? process_one_work+0x3c0/0x3c0 [30.704826] [] kthread+0xed/0x110 [30.704826] [] ? kthread_create_on_node+0x190/0x190 [30.704826] [] ret_from_fork+0x3f/0x70 In this commit, 1. we remove the check for the return code for mod_timer() 2. we protect tipc_subscrb_get() using the subscriber spin lock. We increment the subscriber's refcount as soon as we add the subscription to subscriber's subscription list. Acked-by: Ying Xue Reviewed-by: Jon Maloy Signed-off-by: Parthasarathy Bhuvaragan Signed-off-by: David S. Miller --- diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index e4ebbc1..7d226ec 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -284,13 +284,13 @@ static void tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s, spin_lock_bh(&subscriber->lock); list_add(&sub->subscrp_list, &subscriber->subscrp_list); + tipc_subscrb_get(subscriber); sub->subscriber = subscriber; tipc_nametbl_subscribe(sub); spin_unlock_bh(&subscriber->lock); timeout = htohl(sub->evt.s.timeout, swap); - if (!mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout))) - tipc_subscrb_get(subscriber); + mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout)); } /* Handle one termination request for the subscriber */