On 5/11/20 11:59 AM, Tuong Lien wrote: > When a service subscription is expired or canceled by user, it needs to > be deleted from the subscription list, so that new subscriptions can be > registered (max = 65535 per net). However, there are two issues in code > that can cause such an unused subscription to persist: > > 1) The 'tipc_conn_delete_sub()' has a loop on the subscription list but > it makes a break shortly when the 1st subscription differs from the one > specified, so the subscription will not be deleted. > > 2) In case a subscription is canceled, the code to remove the > 'TIPC_SUB_CANCEL' flag from the subscription filter does not work if it > is a local subscription (i.e. the little endian isn't involved). So, it > will be no matches when looking for the subscription to delete later. > > The subscription(s) will be removed eventually when the user terminates > its topology connection but that could be a long time later. Meanwhile, > the number of available subscriptions may be exhausted. > > This commit fixes the two issues above, so as needed a subscription can > be deleted correctly. > > v2: define a new macro to write sub field value (- Jon's comment) > v3: break if the sub to be deleted has been found > > Signed-off-by: Tuong Lien <tuong.t.l...@dektech.com.au>
Acked-by: Ying Xue <ying....@windriver.com> > --- > net/tipc/subscr.h | 10 ++++++++++ > net/tipc/topsrv.c | 9 +++++---- > 2 files changed, 15 insertions(+), 4 deletions(-) > > diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h > index aa015c233898..6ebbec1bedd1 100644 > --- a/net/tipc/subscr.h > +++ b/net/tipc/subscr.h > @@ -96,6 +96,16 @@ void tipc_sub_get(struct tipc_subscription *subscription); > (swap_ ? swab32(val__) : val__); \ > }) > > +/* tipc_sub_write - write val_ to field_ of struct sub_ in user endian format > + */ > +#define tipc_sub_write(sub_, field_, val_) \ > + ({ \ > + struct tipc_subscr *sub__ = sub_; \ > + u32 val__ = val_; \ > + int swap_ = !((sub__)->filter & TIPC_FILTER_MASK); \ > + (sub__)->field_ = swap_ ? swab32(val__) : val__; \ > + }) > + > /* tipc_evt_write - write val_ to field_ of struct evt_ in user endian format > */ > #define tipc_evt_write(evt_, field_, val_) \ > diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c > index 931c426673c0..446af7bbd13e 100644 > --- a/net/tipc/topsrv.c > +++ b/net/tipc/topsrv.c > @@ -237,8 +237,8 @@ static void tipc_conn_delete_sub(struct tipc_conn *con, > struct tipc_subscr *s) > if (!s || !memcmp(s, &sub->evt.s, sizeof(*s))) { > tipc_sub_unsubscribe(sub); > atomic_dec(&tn->subscription_count); > - } else if (s) { > - break; > + if (s) > + break; > } > } > spin_unlock_bh(&con->sub_lock); > @@ -362,9 +362,10 @@ static int tipc_conn_rcv_sub(struct tipc_topsrv *srv, > { > struct tipc_net *tn = tipc_net(srv->net); > struct tipc_subscription *sub; > + u32 s_filter = tipc_sub_read(s, filter); > > - if (tipc_sub_read(s, filter) & TIPC_SUB_CANCEL) { > - s->filter &= __constant_ntohl(~TIPC_SUB_CANCEL); > + if (s_filter & TIPC_SUB_CANCEL) { > + tipc_sub_write(s, filter, s_filter & ~TIPC_SUB_CANCEL); > tipc_conn_delete_sub(con, s); > return 0; > } > _______________________________________________ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion