On Tue, Feb 21, 2017 at 12:39 AM, Ying Xue <ying....@windriver.com> wrote:
> As the policy of holding subscription in subscriber time has been > adjusted, it's unnecessary to hold subscription refcount before > tipc_subscrp_delete() is called. As a consequence, subscriber->lock > can be safely removed to avoid the following two deadlock scenarios: > > CPU1: CPU2: > ---------- ---------------- > tipc_nametbl_publish > spin_lock_bh(&tn->nametbl_lock) > tipc_nametbl_insert_publ > tipc_nameseq_insert_publ > tipc_subscrp_report_overlap > tipc_subscrp_get > tipc_subscrp_send_event > tipc_close_conn > tipc_subscrb_release_cb > tipc_subscrb_delete > tipc_subscrp_put > tipc_subscrp_put > tipc_subscrp_kref_release > tipc_nametbl_unsubscribe > spin_lock_bh(&tn->nametbl_lock) > <<grab nametbl_lock again>> > > CPU1: CPU2: > ---------- ---------------- > tipc_nametbl_stop > spin_lock_bh(&tn->nametbl_lock) > tipc_purge_publications > tipc_nameseq_remove_publ > tipc_subscrp_report_overlap > tipc_subscrp_get > tipc_subscrp_send_event > tipc_close_conn > tipc_subscrb_release_cb > tipc_subscrb_delete > tipc_subscrp_put > tipc_subscrp_put > tipc_subscrp_kref_release > tipc_nametbl_unsubscribe > spin_lock_bh(&tn->nametbl_lock) > <<grab nametbl_lock again>> > > Reported-by: John Thompson <thompa....@gmail.com> > Reported-by: Jon Maloy <jon.ma...@ericsson.com> > Fixes: d094c4d5f5 ("tipc: add subscription refcount to avoid invalid > delete") > Signed-off-by: Ying Xue <ying....@windriver.com> > --- > net/tipc/subscr.c | 6 ------ > 1 file changed, 6 deletions(-) > > diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c > index 6624232..ea67cce 100644 > --- a/net/tipc/subscr.c > +++ b/net/tipc/subscr.c > @@ -168,9 +168,7 @@ static void tipc_subscrp_kref_release(struct kref > *kref) > struct tipc_net *tn = net_generic(sub->net, tipc_net_id); > struct tipc_subscriber *subscriber = sub->subscriber; > > - spin_lock_bh(&subscriber->lock); > atomic_dec(&tn->subscription_count); > - spin_unlock_bh(&subscriber->lock); > kfree(sub); > tipc_subscrb_put(subscriber); > } > @@ -202,11 +200,7 @@ static void tipc_subscrb_subscrp_delete(struct > tipc_subscriber *subscriber, > list_del(&sub->subscrp_list); > > tipc_nametbl_unsubscribe(sub); > - tipc_subscrp_get(sub); > - spin_unlock_bh(&subscriber->lock); > By removing the unlocking at this point couldn't you end up with a deadlock on subscriber->lock due to tipc_subscrp_delete() putting the subscrp twice (which could end up with kref == 0) and as a result calling tipc_subscrp_kref_release() which gets subscriber->lock? > tipc_subscrp_delete(sub); > - tipc_subscrp_put(sub); > - spin_lock_bh(&subscriber->lock); > > if (s) > break; > -- > 2.7.4 > > ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion