aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAllan Stephens <allan.stephens@windriver.com>2008-04-15 03:15:50 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-15 03:15:50 -0400
commit1819b83718dc3fe0aea0a2c3cd48d617e2003606 (patch)
treeaad3787178db838ac21b8e0dd05b472377cc5a74 /net
parent7a8036c2b93c8301afce8f75ac099c347bad569d (diff)
[TIPC]: Correct "off by 1" error in socket queue limit enforcement
This patch fixes a bug that allowed TIPC to queue 1 more message than allowed by the socket receive queue threshold limits. The patch also improves the threshold code's logic and naming to help prevent this sort of error from recurring in the future. Signed-off-by: Allan Stephens <allan.stephens@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/tipc/socket.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index ead22e5eed32..4c83aba575c5 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1079,15 +1079,15 @@ exit:
1079} 1079}
1080 1080
1081/** 1081/**
1082 * queue_overloaded - test if queue overload condition exists 1082 * rx_queue_full - determine if receive queue can accept another message
1083 * @msg: message to be added to queue
1083 * @queue_size: current size of queue 1084 * @queue_size: current size of queue
1084 * @base: nominal maximum size of queue 1085 * @base: nominal maximum size of queue
1085 * @msg: message to be added to queue
1086 * 1086 *
1087 * Returns 1 if queue is currently overloaded, 0 otherwise 1087 * Returns 1 if queue is unable to accept message, 0 otherwise
1088 */ 1088 */
1089 1089
1090static int queue_overloaded(u32 queue_size, u32 base, struct tipc_msg *msg) 1090static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base)
1091{ 1091{
1092 u32 threshold; 1092 u32 threshold;
1093 u32 imp = msg_importance(msg); 1093 u32 imp = msg_importance(msg);
@@ -1104,7 +1104,7 @@ static int queue_overloaded(u32 queue_size, u32 base, struct tipc_msg *msg)
1104 if (msg_connected(msg)) 1104 if (msg_connected(msg))
1105 threshold *= 4; 1105 threshold *= 4;
1106 1106
1107 return (queue_size > threshold); 1107 return (queue_size >= threshold);
1108} 1108}
1109 1109
1110/** 1110/**
@@ -1189,16 +1189,14 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
1189 1189
1190 /* Reject message if there isn't room to queue it */ 1190 /* Reject message if there isn't room to queue it */
1191 1191
1192 if (unlikely((u32)atomic_read(&tipc_queue_size) > 1192 recv_q_len = (u32)atomic_read(&tipc_queue_size);
1193 OVERLOAD_LIMIT_BASE)) { 1193 if (unlikely(recv_q_len >= OVERLOAD_LIMIT_BASE)) {
1194 if (queue_overloaded(atomic_read(&tipc_queue_size), 1194 if (rx_queue_full(msg, recv_q_len, OVERLOAD_LIMIT_BASE))
1195 OVERLOAD_LIMIT_BASE, msg))
1196 return TIPC_ERR_OVERLOAD; 1195 return TIPC_ERR_OVERLOAD;
1197 } 1196 }
1198 recv_q_len = skb_queue_len(&tsock->sk.sk_receive_queue); 1197 recv_q_len = skb_queue_len(&tsock->sk.sk_receive_queue);
1199 if (unlikely(recv_q_len > (OVERLOAD_LIMIT_BASE / 2))) { 1198 if (unlikely(recv_q_len >= (OVERLOAD_LIMIT_BASE / 2))) {
1200 if (queue_overloaded(recv_q_len, 1199 if (rx_queue_full(msg, recv_q_len, OVERLOAD_LIMIT_BASE / 2))
1201 OVERLOAD_LIMIT_BASE / 2, msg))
1202 return TIPC_ERR_OVERLOAD; 1200 return TIPC_ERR_OVERLOAD;
1203 } 1201 }
1204 1202