From: Jon Maloy <jon.maloy@ericsson.com>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org,
Paul Gortmaker <paul.gortmaker@windriver.com>,
erik.hugne@ericsson.com, ying.xue@windriver.com,
maloy@donjonn.com, tipc-discussion@lists.sourceforge.net,
Jon Maloy <jon.maloy@ericsson.com>
Subject: [PATCH net-next 03/13] tipc: move link input queue to tipc_node
Date: Thu, 16 Jul 2015 16:54:21 -0400 [thread overview]
Message-ID: <1437080071-6686-4-git-send-email-jon.maloy@ericsson.com> (raw)
In-Reply-To: <1437080071-6686-1-git-send-email-jon.maloy@ericsson.com>
At present, the link input queue and the name distributor receive
queues are fields aggregated in struct tipc_link. This is a hazard,
because a link might be deleted while a receiving socket still keeps
reference to one of the queues.
This commit fixes this bug. However, rather than adding yet another
reference counter to the critical data path, we move the two queues
to safe ground inside struct tipc_node, which is already protected, and
let the link code only handle references to the queues. This is also
in line with planned later changes in this area.
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/link.c | 27 +++++++++++++++------------
net/tipc/link.h | 12 +++++++-----
net/tipc/node.c | 4 +++-
net/tipc/node.h | 3 ++-
4 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 03372a7..f8e0e2c 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -227,7 +227,9 @@ static void link_set_timer(struct tipc_link *link, unsigned long time)
*/
struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
struct tipc_bearer *b_ptr,
- const struct tipc_media_addr *media_addr)
+ const struct tipc_media_addr *media_addr,
+ struct sk_buff_head *inputq,
+ struct sk_buff_head *namedq)
{
struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id);
struct tipc_link *l_ptr;
@@ -289,8 +291,9 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
__skb_queue_head_init(&l_ptr->backlogq);
__skb_queue_head_init(&l_ptr->deferdq);
skb_queue_head_init(&l_ptr->wakeupq);
- skb_queue_head_init(&l_ptr->inputq);
- skb_queue_head_init(&l_ptr->namedq);
+ l_ptr->inputq = inputq;
+ l_ptr->namedq = namedq;
+ skb_queue_head_init(l_ptr->inputq);
link_reset_statistics(l_ptr);
tipc_node_attach_link(n_ptr, l_ptr);
setup_timer(&l_ptr->timer, link_timeout, (unsigned long)l_ptr);
@@ -391,8 +394,8 @@ void link_prepare_wakeup(struct tipc_link *l)
if ((pnd[imp] + l->backlog[imp].len) >= lim)
break;
skb_unlink(skb, &l->wakeupq);
- skb_queue_tail(&l->inputq, skb);
- l->owner->inputq = &l->inputq;
+ skb_queue_tail(l->inputq, skb);
+ l->owner->inputq = l->inputq;
l->owner->action_flags |= TIPC_MSG_EVT;
}
}
@@ -465,7 +468,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
__skb_queue_purge(&l_ptr->transmq);
__skb_queue_purge(&l_ptr->deferdq);
if (!owner->inputq)
- owner->inputq = &l_ptr->inputq;
+ owner->inputq = l_ptr->inputq;
skb_queue_splice_init(&l_ptr->wakeupq, owner->inputq);
if (!skb_queue_empty(owner->inputq))
owner->action_flags |= TIPC_MSG_EVT;
@@ -962,7 +965,7 @@ static bool link_synch(struct tipc_link *l)
/* Is it still in the input queue ? */
post_synch = mod(pl->rcv_nxt - l->synch_point) - 1;
- if (skb_queue_len(&pl->inputq) > post_synch)
+ if (skb_queue_len(pl->inputq) > post_synch)
return false;
synched:
l->flags &= ~LINK_SYNCHING;
@@ -1141,16 +1144,16 @@ static bool tipc_data_input(struct tipc_link *link, struct sk_buff *skb)
case TIPC_HIGH_IMPORTANCE:
case TIPC_CRITICAL_IMPORTANCE:
case CONN_MANAGER:
- if (tipc_skb_queue_tail(&link->inputq, skb, dport)) {
- node->inputq = &link->inputq;
+ if (tipc_skb_queue_tail(link->inputq, skb, dport)) {
+ node->inputq = link->inputq;
node->action_flags |= TIPC_MSG_EVT;
}
return true;
case NAME_DISTRIBUTOR:
node->bclink.recv_permitted = true;
- node->namedq = &link->namedq;
- skb_queue_tail(&link->namedq, skb);
- if (skb_queue_len(&link->namedq) == 1)
+ node->namedq = link->namedq;
+ skb_queue_tail(link->namedq, skb);
+ if (skb_queue_len(link->namedq) == 1)
node->action_flags |= TIPC_NAMED_MSG_EVT;
return true;
case MSG_BUNDLER:
diff --git a/net/tipc/link.h b/net/tipc/link.h
index ae0a0ea..9c71d9e 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -192,8 +192,8 @@ struct tipc_link {
u16 rcv_nxt;
u32 rcv_unacked;
struct sk_buff_head deferdq;
- struct sk_buff_head inputq;
- struct sk_buff_head namedq;
+ struct sk_buff_head *inputq;
+ struct sk_buff_head *namedq;
/* Congestion handling */
struct sk_buff_head wakeupq;
@@ -207,9 +207,11 @@ struct tipc_link {
struct tipc_port;
-struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
- struct tipc_bearer *b_ptr,
- const struct tipc_media_addr *media_addr);
+struct tipc_link *tipc_link_create(struct tipc_node *n,
+ struct tipc_bearer *b,
+ const struct tipc_media_addr *maddr,
+ struct sk_buff_head *inputq,
+ struct sk_buff_head *namedq);
void tipc_link_delete(struct tipc_link *link);
void tipc_link_delete_list(struct net *net, unsigned int bearer_id);
void tipc_link_failover_send_queue(struct tipc_link *l_ptr);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 06f642a..20ec61c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -132,6 +132,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr)
INIT_LIST_HEAD(&n_ptr->list);
INIT_LIST_HEAD(&n_ptr->publ_list);
INIT_LIST_HEAD(&n_ptr->conn_sks);
+ skb_queue_head_init(&n_ptr->bclink.namedq);
__skb_queue_head_init(&n_ptr->bclink.deferdq);
hlist_add_head_rcu(&n_ptr->hash, &tn->node_htable[tipc_hashfn(addr)]);
list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
@@ -350,9 +351,10 @@ bool tipc_node_update_dest(struct tipc_node *n, struct tipc_bearer *b,
{
struct tipc_link *l = n->links[b->identity].link;
struct tipc_media_addr *curr = &n->links[b->identity].maddr;
+ struct sk_buff_head *inputq = &n->links[b->identity].inputq;
if (!l)
- l = tipc_link_create(n, b, maddr);
+ l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq);
if (!l)
return false;
memcpy(&l->media_addr, maddr, sizeof(*maddr));
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 68579c7..0657cbf 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -85,13 +85,14 @@ struct tipc_node_bclink {
u32 deferred_size;
struct sk_buff_head deferdq;
struct sk_buff *reasm_buf;
- int inputq_map;
+ struct sk_buff_head namedq;
bool recv_permitted;
};
struct tipc_link_entry {
struct tipc_link *link;
u32 mtu;
+ struct sk_buff_head inputq;
struct tipc_media_addr maddr;
};
--
1.9.1
next prev parent reply other threads:[~2015-07-16 20:54 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-16 20:54 [PATCH net-next 00/13] tipc: separate link and link aggregation layer Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 01/13] tipc: introduce link entry structure to struct tipc_node Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 02/13] tipc: move link creation from neighbor discoverer to node Jon Maloy
2015-07-16 20:54 ` Jon Maloy [this message]
2015-07-16 20:54 ` [PATCH net-next 04/13] tipc: use bearer index when looking up active links Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 05/13] tipc: change sk_buffer handling in tipc_link_xmit() Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 06/13] tipc: make media xmit call outside node spinlock context Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 07/13] tipc: clean up definitions and usage of link flags Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 08/13] tipc: introduce new link protocol msg create function Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 09/13] tipc: improve link FSM implementation Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 10/13] tipc: simplify link timer implementation Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 11/13] tipc: move link supervision timer to node level Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 12/13] tipc: introduce node contact FSM Jon Maloy
2015-07-16 20:54 ` [PATCH net-next 13/13] tipc: reduce locking scope during packet reception Jon Maloy
2015-07-21 3:41 ` [PATCH net-next 00/13] tipc: separate link and link aggregation layer David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1437080071-6686-4-git-send-email-jon.maloy@ericsson.com \
--to=jon.maloy@ericsson.com \
--cc=davem@davemloft.net \
--cc=erik.hugne@ericsson.com \
--cc=maloy@donjonn.com \
--cc=netdev@vger.kernel.org \
--cc=paul.gortmaker@windriver.com \
--cc=tipc-discussion@lists.sourceforge.net \
--cc=ying.xue@windriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).