forked from Minki/linux
tipc: modify struct tipc_plist to be more versatile
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_'. We also add a couple of new functions which will come to use in the next commits. Acked-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com> Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8c44e1af16
commit
4d8642d896
@ -608,7 +608,7 @@ not_found:
|
||||
* 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 tipc_plist *nl;
|
||||
struct u32_item {
|
||||
struct list_head list;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
if (likely(!pl->port)) {
|
||||
pl->port = port;
|
||||
return;
|
||||
bool u32_find(struct list_head *l, u32 value)
|
||||
{
|
||||
struct u32_item *item;
|
||||
|
||||
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;
|
||||
}
|
||||
nl = kmalloc(sizeof(*nl), GFP_ATOMIC);
|
||||
if (nl) {
|
||||
nl->port = port;
|
||||
list_add(&nl->list, &pl->list);
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -788,7 +788,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;
|
||||
@ -796,7 +796,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)) {
|
||||
@ -810,8 +810,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);
|
||||
|
Loading…
Reference in New Issue
Block a user