提交 3fa6b5ad 编写于 作者: H Hendrik Brueckner 提交者: David S. Miller

af_iucv: Fix race when queuing incoming iucv messages

AF_IUCV runs into a race when queuing incoming iucv messages
and receiving the resulting backlog.

If the Linux system is under pressure (high load or steal time),
the message queue grows up, but messages are not received and queued
onto the backlog queue. In that case, applications do not
receive any data with recvmsg() even if AF_IUCV puts incoming
messages onto the message queue.

The race can be avoided if the message queue spinlock in the
message_pending callback is spreaded across the entire callback
function.
Signed-off-by: NHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: NUrsula Braun <ursula.braun@de.ibm.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 e14ad5fa
...@@ -1124,6 +1124,8 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) ...@@ -1124,6 +1124,8 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
return; return;
} }
spin_lock(&iucv->message_q.lock);
if (!list_empty(&iucv->message_q.list) || if (!list_empty(&iucv->message_q.list) ||
!skb_queue_empty(&iucv->backlog_skb_q)) !skb_queue_empty(&iucv->backlog_skb_q))
goto save_message; goto save_message;
...@@ -1137,9 +1139,8 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) ...@@ -1137,9 +1139,8 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
if (!skb) if (!skb)
goto save_message; goto save_message;
spin_lock(&iucv->message_q.lock);
iucv_process_message(sk, skb, path, msg); iucv_process_message(sk, skb, path, msg);
spin_unlock(&iucv->message_q.lock); goto out_unlock;
return; return;
...@@ -1150,8 +1151,9 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) ...@@ -1150,8 +1151,9 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
save_msg->path = path; save_msg->path = path;
save_msg->msg = *msg; save_msg->msg = *msg;
spin_lock(&iucv->message_q.lock);
list_add_tail(&save_msg->list, &iucv->message_q.list); list_add_tail(&save_msg->list, &iucv->message_q.list);
out_unlock:
spin_unlock(&iucv->message_q.lock); spin_unlock(&iucv->message_q.lock);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册