aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/msg.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2014-08-22 18:09:07 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-23 14:18:33 -0400
commit50100a5e39461b2a61d6040e73c384766c29975d (patch)
tree7f632d0f22af7f38c282603e5c9f4de3139bce59 /net/tipc/msg.c
parent1dd0bd2b14032037d40a316dd52370f1713fa62b (diff)
tipc: use pseudo message to wake up sockets after link congestion
The current link implementation keeps a linked list of blocked ports/ sockets that is populated when there is link congestion. The purpose of this is to let the link know which users to wake up when the congestion abates. This adds unnecessary complexity to the data structure and the code, since it forces us to involve the link each time we want to delete a socket. It also forces us to grab the spinlock port_lock within the scope of node_lock. We want to get rid of this direct dependence, as well as the deadlock hazard resulting from the usage of port_lock. In this commit, we instead let the link keep list of a "wakeup" pseudo messages for use in such situations. Those messages are sent to the pending sockets via the ordinary message reception path, and wake up the socket's owner when they are received. This enables us to get rid of the 'waiting_ports' linked lists in struct tipc_port that manifest this direct reference. As a consequence, we can eliminate another BH entry into the socket, and hence the need to grab port_lock. This is a further step in our effort to remove port_lock altogether. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r--net/tipc/msg.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index fdb92e247050..74745a47d72a 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -182,7 +182,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
182 struct sk_buff *buf, *prev; 182 struct sk_buff *buf, *prev;
183 char *pktpos; 183 char *pktpos;
184 int rc; 184 int rc;
185 185 uint chain_sz = 0;
186 msg_set_size(mhdr, msz); 186 msg_set_size(mhdr, msz);
187 187
188 /* No fragmentation needed? */ 188 /* No fragmentation needed? */
@@ -193,6 +193,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
193 return -ENOMEM; 193 return -ENOMEM;
194 skb_copy_to_linear_data(buf, mhdr, mhsz); 194 skb_copy_to_linear_data(buf, mhdr, mhsz);
195 pktpos = buf->data + mhsz; 195 pktpos = buf->data + mhsz;
196 TIPC_SKB_CB(buf)->chain_sz = 1;
196 if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz)) 197 if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz))
197 return dsz; 198 return dsz;
198 rc = -EFAULT; 199 rc = -EFAULT;
@@ -209,6 +210,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
209 *chain = buf = tipc_buf_acquire(pktmax); 210 *chain = buf = tipc_buf_acquire(pktmax);
210 if (!buf) 211 if (!buf)
211 return -ENOMEM; 212 return -ENOMEM;
213 chain_sz = 1;
212 pktpos = buf->data; 214 pktpos = buf->data;
213 skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE); 215 skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE);
214 pktpos += INT_H_SIZE; 216 pktpos += INT_H_SIZE;
@@ -242,6 +244,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
242 rc = -ENOMEM; 244 rc = -ENOMEM;
243 goto error; 245 goto error;
244 } 246 }
247 chain_sz++;
245 prev->next = buf; 248 prev->next = buf;
246 msg_set_type(&pkthdr, FRAGMENT); 249 msg_set_type(&pkthdr, FRAGMENT);
247 msg_set_size(&pkthdr, pktsz); 250 msg_set_size(&pkthdr, pktsz);
@@ -251,7 +254,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
251 pktrem = pktsz - INT_H_SIZE; 254 pktrem = pktsz - INT_H_SIZE;
252 255
253 } while (1); 256 } while (1);
254 257 TIPC_SKB_CB(*chain)->chain_sz = chain_sz;
255 msg_set_type(buf_msg(buf), LAST_FRAGMENT); 258 msg_set_type(buf_msg(buf), LAST_FRAGMENT);
256 return dsz; 259 return dsz;
257error: 260error: