Hi Ying,

Sorry I sent that reply before signing it off.
The rest of the changes look like they are doing the right things but this
change looks like it has the potential to cause a deadlock.

Regards,
John

On Tue, Feb 21, 2017 at 11:13 AM, John Thompson <thompa....@gmail.com>
wrote:

>
>
> 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

Reply via email to