On 12/13/2016 06:42 AM, Jon Maloy wrote: > During multicast reception we currently use a simple linked list with > push/pop semantics to store port numbers. > > We now see a need for a more generic list for storing values of type > u32. We therefore make some modifications to this list, while replacing > the prefix 'tipc_plist_' with 'u32_'.
It's a shame that we cannot use interfaces defined in lib/plist.c, otherwise, it's unnecessary for us to implement by ourselves. I still prefer to use "tipc_u32" prefix because the function names are a bit too generic without "tipc". Especially when we analyze stack trace, common function names cause a bit inconvenience for us. Regards, Ying We also add a couple of new > functions which will come to use in the next commits. > > Signed-off-by: Jon Maloy <[email protected]> > --- > net/tipc/name_table.c | 100 > ++++++++++++++++++++++++++++++++++++-------------- > net/tipc/name_table.h | 21 ++++------- > net/tipc/socket.c | 8 ++-- > 3 files changed, 83 insertions(+), 46 deletions(-) > > diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c > index e190460..5a86df1 100644 > --- a/net/tipc/name_table.c > +++ b/net/tipc/name_table.c > @@ -608,7 +608,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 > instance, > * Returns non-zero if any off-node ports overlap > */ > int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 > upper, > - u32 limit, struct tipc_plist *dports) > + u32 limit, struct list_head *dports) > { > struct name_seq *seq; > struct sub_seq *sseq; > @@ -633,7 +633,7 @@ int tipc_nametbl_mc_translate(struct net *net, u32 type, > u32 lower, u32 upper, > info = sseq->info; > list_for_each_entry(publ, &info->node_list, node_list) { > if (publ->scope <= limit) > - tipc_plist_push(dports, publ->ref); > + u32_push(dports, publ->ref); > } > > if (info->cluster_list_size != info->node_list_size) > @@ -1022,40 +1022,84 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, > struct netlink_callback *cb) > return skb->len; > } > > -void tipc_plist_push(struct tipc_plist *pl, u32 port) > +struct u32_item { > + struct list_head list; > + u32 value; > +}; > + > +bool u32_find(struct list_head *l, u32 value) > { > - struct tipc_plist *nl; > + struct u32_item *item; > > - if (likely(!pl->port)) { > - pl->port = port; > - return; > + list_for_each_entry(item, l, list) { > + if (item->value == value) > + return true; > } > - if (pl->port == port) > - return; > - list_for_each_entry(nl, &pl->list, list) { > - if (nl->port == port) > - return; > + return false; > +} > + > +bool u32_push(struct list_head *l, u32 value) > +{ > + struct u32_item *item; > + > + list_for_each_entry(item, l, list) { > + if (item->value == value) > + return false; > + } > + item = kmalloc(sizeof(*item), GFP_ATOMIC); > + if (unlikely(!item)) > + return false; > + > + item->value = value; > + list_add(&item->list, l); > + return true; > +} > + > +u32 u32_pop(struct list_head *l) > +{ > + struct u32_item *item; > + u32 value = 0; > + > + if (list_empty(l)) > + return 0; > + item = list_first_entry(l, typeof(*item), list); > + value = item->value; > + list_del(&item->list); > + kfree(item); > + return value; > +} > + > +bool u32_del(struct list_head *l, u32 value) > +{ > + struct u32_item *item, *tmp; > + > + list_for_each_entry_safe(item, tmp, l, list) { > + if (item->value != value) > + continue; > + list_del(&item->list); > + kfree(item); > + return true; > } > - nl = kmalloc(sizeof(*nl), GFP_ATOMIC); > - if (nl) { > - nl->port = port; > - list_add(&nl->list, &pl->list); > + return false; > +} > + > +void u32_list_purge(struct list_head *l) > +{ > + struct u32_item *item, *tmp; > + > + list_for_each_entry_safe(item, tmp, l, list) { > + list_del(&item->list); > + kfree(item); > } > } > > -u32 tipc_plist_pop(struct tipc_plist *pl) > +int u32_list_len(struct list_head *l) > { > - struct tipc_plist *nl; > - u32 port = 0; > + struct u32_item *item; > + int i = 0; > > - if (likely(list_empty(&pl->list))) { > - port = pl->port; > - pl->port = 0; > - return port; > + list_for_each_entry(item, l, list) { > + i++; > } > - nl = list_first_entry(&pl->list, typeof(*nl), list); > - port = nl->port; > - list_del(&nl->list); > - kfree(nl); > - return port; > + return i; > } > diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h > index 1524a73..c89bb3f 100644 > --- a/net/tipc/name_table.h > +++ b/net/tipc/name_table.h > @@ -99,7 +99,7 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct > netlink_callback *cb); > > u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 > *node); > int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 > upper, > - u32 limit, struct tipc_plist *dports); > + u32 limit, struct list_head *dports); > struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 > lower, > u32 upper, u32 scope, u32 port_ref, > u32 key); > @@ -116,18 +116,11 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription > *s); > int tipc_nametbl_init(struct net *net); > void tipc_nametbl_stop(struct net *net); > > -struct tipc_plist { > - struct list_head list; > - u32 port; > -}; > - > -static inline void tipc_plist_init(struct tipc_plist *pl) > -{ > - INIT_LIST_HEAD(&pl->list); > - pl->port = 0; > -} > - > -void tipc_plist_push(struct tipc_plist *pl, u32 port); > -u32 tipc_plist_pop(struct tipc_plist *pl); > +bool u32_push(struct list_head *l, u32 value); > +u32 u32_pop(struct list_head *l); > +bool u32_find(struct list_head *l, u32 value); > +bool u32_del(struct list_head *l, u32 value); > +void u32_list_purge(struct list_head *l); > +int u32_list_len(struct list_head *l); > > #endif > diff --git a/net/tipc/socket.c b/net/tipc/socket.c > index 8f3ab08..629b659 100644 > --- a/net/tipc/socket.c > +++ b/net/tipc/socket.c > @@ -786,7 +786,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct > sk_buff_head *arrvq, > struct sk_buff_head *inputq) > { > struct tipc_msg *msg; > - struct tipc_plist dports; > + struct list_head dports; > u32 portid; > u32 scope = TIPC_CLUSTER_SCOPE; > struct sk_buff_head tmpq; > @@ -794,7 +794,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct > sk_buff_head *arrvq, > struct sk_buff *skb, *_skb; > > __skb_queue_head_init(&tmpq); > - tipc_plist_init(&dports); > + INIT_LIST_HEAD(&dports); > > skb = tipc_skb_peek(arrvq, &inputq->lock); > for (; skb; skb = tipc_skb_peek(arrvq, &inputq->lock)) { > @@ -808,8 +808,8 @@ void tipc_sk_mcast_rcv(struct net *net, struct > sk_buff_head *arrvq, > tipc_nametbl_mc_translate(net, > msg_nametype(msg), msg_namelower(msg), > msg_nameupper(msg), scope, &dports); > - portid = tipc_plist_pop(&dports); > - for (; portid; portid = tipc_plist_pop(&dports)) { > + portid = u32_pop(&dports); > + for (; portid; portid = u32_pop(&dports)) { > _skb = __pskb_copy(skb, hsz, GFP_ATOMIC); > if (_skb) { > msg_set_destport(buf_msg(_skb), portid); > ------------------------------------------------------------------------------ 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 [email protected] https://lists.sourceforge.net/lists/listinfo/tipc-discussion
