]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: af_iucv: Fix race when queuing incoming iucv messages | |
3 | References: bnc#499845,LTC#53033 | |
4 | ||
5 | Symptom: A socket application does not receive any new data even | |
6 | if incoming IUCV messages are received and queued. | |
7 | Problem: AF_IUCV runs into a race when queueing incoming iucv | |
8 | messages and receiving the resulting backlog. | |
9 | If the Linux system is under pressure (high load or | |
10 | steal time), the message queue grows up, but messages | |
11 | are not received and queued onto the backlog queue. | |
12 | In that case, applications do not receive any data with | |
13 | recvmsg() even if AF_IUCV puts incoming messages onto | |
14 | the message queue. | |
15 | Solution: The race can be avoided if the message queue | |
16 | spinlock in the message_pending callback is | |
17 | spreaded across the entire callback function. | |
18 | ||
19 | Acked-by: John Jolly <jjolly@suse.de> | |
20 | --- | |
21 | net/iucv/af_iucv.c | 10 +++++----- | |
22 | 1 file changed, 5 insertions(+), 5 deletions(-) | |
23 | ||
24 | --- a/net/iucv/af_iucv.c | |
25 | +++ b/net/iucv/af_iucv.c | |
26 | @@ -1089,6 +1089,8 @@ static void iucv_callback_rx(struct iucv | |
27 | if (sk->sk_shutdown & RCV_SHUTDOWN) | |
28 | return; | |
29 | ||
30 | + spin_lock(&iucv->message_q.lock); | |
31 | + | |
32 | if (!list_empty(&iucv->message_q.list) || | |
33 | !skb_queue_empty(&iucv->backlog_skb_q)) | |
34 | goto save_message; | |
35 | @@ -1102,11 +1104,8 @@ static void iucv_callback_rx(struct iucv | |
36 | if (!skb) | |
37 | goto save_message; | |
38 | ||
39 | - spin_lock(&iucv->message_q.lock); | |
40 | iucv_process_message(sk, skb, path, msg); | |
41 | - spin_unlock(&iucv->message_q.lock); | |
42 | - | |
43 | - return; | |
44 | + goto out_unlock; | |
45 | ||
46 | save_message: | |
47 | save_msg = kzalloc(sizeof(struct sock_msg_q), GFP_ATOMIC | GFP_DMA); | |
48 | @@ -1115,8 +1114,9 @@ save_message: | |
49 | save_msg->path = path; | |
50 | save_msg->msg = *msg; | |
51 | ||
52 | - spin_lock(&iucv->message_q.lock); | |
53 | list_add_tail(&save_msg->list, &iucv->message_q.list); | |
54 | + | |
55 | +out_unlock: | |
56 | spin_unlock(&iucv->message_q.lock); | |
57 | } | |
58 |