Commit 30b38236 authored by David S. Miller's avatar David S. Miller

Merge branch 'tipc-subscription-refcount-simplifications'

Parthasarathy Bhuvaragan says:

====================
tipc: subscription refcount simplifications

The first patch makes the subscription refcount cleanup lockless and
the second updates the subscription refcount policy.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 589a1a2e 7efea60d
...@@ -416,6 +416,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, ...@@ -416,6 +416,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq,
tipc_subscrp_convert_seq(&s->evt.s.seq, s->swap, &ns); tipc_subscrp_convert_seq(&s->evt.s.seq, s->swap, &ns);
tipc_subscrp_get(s);
list_add(&s->nameseq_list, &nseq->subscriptions); list_add(&s->nameseq_list, &nseq->subscriptions);
if (!sseq) if (!sseq)
...@@ -787,6 +788,7 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s) ...@@ -787,6 +788,7 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s)
if (seq != NULL) { if (seq != NULL) {
spin_lock_bh(&seq->lock); spin_lock_bh(&seq->lock);
list_del_init(&s->nameseq_list); list_del_init(&s->nameseq_list);
tipc_subscrp_put(s);
if (!seq->first_free && list_empty(&seq->subscriptions)) { if (!seq->first_free && list_empty(&seq->subscriptions)) {
hlist_del_init_rcu(&seq->ns_list); hlist_del_init_rcu(&seq->ns_list);
kfree(seq->sseqs); kfree(seq->sseqs);
......
...@@ -54,8 +54,6 @@ struct tipc_subscriber { ...@@ -54,8 +54,6 @@ struct tipc_subscriber {
static void tipc_subscrp_delete(struct tipc_subscription *sub); static void tipc_subscrp_delete(struct tipc_subscription *sub);
static void tipc_subscrb_put(struct tipc_subscriber *subscriber); static void tipc_subscrb_put(struct tipc_subscriber *subscriber);
static void tipc_subscrp_put(struct tipc_subscription *subscription);
static void tipc_subscrp_get(struct tipc_subscription *subscription);
/** /**
* htohl - convert value to endianness used by destination * htohl - convert value to endianness used by destination
...@@ -125,7 +123,6 @@ void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, ...@@ -125,7 +123,6 @@ void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower,
{ {
struct tipc_name_seq seq; struct tipc_name_seq seq;
tipc_subscrp_get(sub);
tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq); tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq);
if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper)) if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper))
return; return;
...@@ -135,7 +132,6 @@ void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, ...@@ -135,7 +132,6 @@ void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower,
tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref, tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref,
node); node);
tipc_subscrp_put(sub);
} }
static void tipc_subscrp_timeout(unsigned long data) static void tipc_subscrp_timeout(unsigned long data)
...@@ -145,6 +141,7 @@ static void tipc_subscrp_timeout(unsigned long data) ...@@ -145,6 +141,7 @@ static void tipc_subscrp_timeout(unsigned long data)
spin_lock_bh(&subscriber->lock); spin_lock_bh(&subscriber->lock);
tipc_nametbl_unsubscribe(sub); tipc_nametbl_unsubscribe(sub);
list_del(&sub->subscrp_list);
spin_unlock_bh(&subscriber->lock); spin_unlock_bh(&subscriber->lock);
/* Notify subscriber of timeout */ /* Notify subscriber of timeout */
...@@ -177,20 +174,17 @@ static void tipc_subscrp_kref_release(struct kref *kref) ...@@ -177,20 +174,17 @@ static void tipc_subscrp_kref_release(struct kref *kref)
struct tipc_net *tn = net_generic(sub->net, tipc_net_id); struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
struct tipc_subscriber *subscriber = sub->subscriber; struct tipc_subscriber *subscriber = sub->subscriber;
spin_lock_bh(&subscriber->lock);
list_del(&sub->subscrp_list);
atomic_dec(&tn->subscription_count); atomic_dec(&tn->subscription_count);
spin_unlock_bh(&subscriber->lock);
kfree(sub); kfree(sub);
tipc_subscrb_put(subscriber); tipc_subscrb_put(subscriber);
} }
static void tipc_subscrp_put(struct tipc_subscription *subscription) void tipc_subscrp_put(struct tipc_subscription *subscription)
{ {
kref_put(&subscription->kref, tipc_subscrp_kref_release); kref_put(&subscription->kref, tipc_subscrp_kref_release);
} }
static void tipc_subscrp_get(struct tipc_subscription *subscription) void tipc_subscrp_get(struct tipc_subscription *subscription)
{ {
kref_get(&subscription->kref); kref_get(&subscription->kref);
} }
...@@ -210,11 +204,8 @@ static void tipc_subscrb_subscrp_delete(struct tipc_subscriber *subscriber, ...@@ -210,11 +204,8 @@ static void tipc_subscrb_subscrp_delete(struct tipc_subscriber *subscriber,
continue; continue;
tipc_nametbl_unsubscribe(sub); tipc_nametbl_unsubscribe(sub);
tipc_subscrp_get(sub); list_del(&sub->subscrp_list);
spin_unlock_bh(&subscriber->lock);
tipc_subscrp_delete(sub); tipc_subscrp_delete(sub);
tipc_subscrp_put(sub);
spin_lock_bh(&subscriber->lock);
if (s) if (s)
break; break;
......
...@@ -78,4 +78,7 @@ u32 tipc_subscrp_convert_seq_type(u32 type, int swap); ...@@ -78,4 +78,7 @@ u32 tipc_subscrp_convert_seq_type(u32 type, int swap);
int tipc_topsrv_start(struct net *net); int tipc_topsrv_start(struct net *net);
void tipc_topsrv_stop(struct net *net); void tipc_topsrv_stop(struct net *net);
void tipc_subscrp_put(struct tipc_subscription *subscription);
void tipc_subscrp_get(struct tipc_subscription *subscription);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment