mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 16:41:25 +00:00
tipc: resolve race problem at unicast message reception
TIPC handles message cardinality and sequencing at the link layer, before passing messages upwards to the destination sockets. During the upcall from link to socket no locks are held. It is therefore possible, and we see it happen occasionally, that messages arriving in different threads and delivered in sequence still bypass each other before they reach the destination socket. This must not happen, since it violates the sequentiality guarantee. We solve this by adding a new input buffer queue to the link structure. Arriving messages are added safely to the tail of that queue by the link, while the head of the queue is consumed, also safely, by the receiving socket. Sequentiality is secured per socket by only allowing buffers to be dequeued inside the socket lock. Since there may be multiple simultaneous readers of the queue, we use a 'filter' parameter to reduce the risk that they peek the same buffer from the queue, hence also reducing the risk of contention on the receiving socket locks. This solves the sequentiality problem, and seems to cause no measurable performance degradation. A nice side effect of this change is that lock handling in the functions tipc_rcv() and tipc_bcast_rcv() now becomes uniform, something that will enable future simplifications of those functions. Reviewed-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
94153e36e7
commit
c637c10355
11 changed files with 375 additions and 244 deletions
|
@ -55,14 +55,15 @@
|
|||
* TIPC_DISTRIBUTE_NAME: publish or withdraw link state name type
|
||||
*/
|
||||
enum {
|
||||
TIPC_MSG_EVT = 1,
|
||||
TIPC_WAIT_PEER_LINKS_DOWN = (1 << 1),
|
||||
TIPC_WAIT_OWN_LINKS_DOWN = (1 << 2),
|
||||
TIPC_NOTIFY_NODE_DOWN = (1 << 3),
|
||||
TIPC_NOTIFY_NODE_UP = (1 << 4),
|
||||
TIPC_WAKEUP_USERS = (1 << 5),
|
||||
TIPC_WAKEUP_BCAST_USERS = (1 << 6),
|
||||
TIPC_NOTIFY_LINK_UP = (1 << 7),
|
||||
TIPC_NOTIFY_LINK_DOWN = (1 << 8)
|
||||
TIPC_WAKEUP_BCAST_USERS = (1 << 5),
|
||||
TIPC_NOTIFY_LINK_UP = (1 << 6),
|
||||
TIPC_NOTIFY_LINK_DOWN = (1 << 7),
|
||||
TIPC_NAMED_MSG_EVT = (1 << 8)
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -92,6 +93,9 @@ struct tipc_node_bclink {
|
|||
* @lock: spinlock governing access to structure
|
||||
* @net: the applicable net namespace
|
||||
* @hash: links to adjacent nodes in unsorted hash chain
|
||||
* @inputq: pointer to input queue containing messages for msg event
|
||||
* @namedq: pointer to name table input queue with name table messages
|
||||
* @curr_link: the link holding the node lock, if any
|
||||
* @active_links: pointers to active links to node
|
||||
* @links: pointers to all links to node
|
||||
* @action_flags: bit mask of different types of node actions
|
||||
|
@ -109,10 +113,12 @@ struct tipc_node {
|
|||
spinlock_t lock;
|
||||
struct net *net;
|
||||
struct hlist_node hash;
|
||||
struct sk_buff_head *inputq;
|
||||
struct sk_buff_head *namedq;
|
||||
struct tipc_link *active_links[2];
|
||||
u32 act_mtus[2];
|
||||
struct tipc_link *links[MAX_BEARERS];
|
||||
unsigned int action_flags;
|
||||
int action_flags;
|
||||
struct tipc_node_bclink bclink;
|
||||
struct list_head list;
|
||||
int link_cnt;
|
||||
|
@ -120,7 +126,6 @@ struct tipc_node {
|
|||
u32 signature;
|
||||
u32 link_id;
|
||||
struct list_head publ_list;
|
||||
struct sk_buff_head waiting_sks;
|
||||
struct list_head conn_sks;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue