]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.xen/849-sfc-tx-skb-lock.patch
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.xen / 849-sfc-tx-skb-lock.patch
1 From: http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/3a4410c4504e
2 # HG changeset 849 patch
3 # User Keir Fraser <keir.fraser@citrix.com>
4 # Date 1238497253 -3600
5 # Node ID 3a4410c4504ea64f2c1e873df3234938366050ad
6 # Parent ab1d4fbbe4bf93f203e0c4d62c18bd248e4f1d4a
7 Subject: sfc_netfront: Only clear tx_skb when ready for netif_wake_queue
8 (doing otherwise could result in a lost packet) and document use of
9 locks to protect tx_skb
10 References: bnc#489721
11 Patch-mainline: obsolete
12
13 Signed-off-by: Kieran Mansley <kmansley@solarflare.com>
14 Acked-by: jbeulich@novell.com
15
16 --- sle11-2009-04-09.orig/drivers/xen/sfc_netfront/accel.h 2009-04-09 14:23:18.000000000 +0200
17 +++ sle11-2009-04-09/drivers/xen/sfc_netfront/accel.h 2009-04-09 14:41:38.000000000 +0200
18 @@ -261,8 +261,10 @@ typedef struct netfront_accel_vnic {
19
20 int poll_enabled;
21
22 - /** A spare slot for a TX packet. This is treated as an extension
23 - * of the DMA queue. */
24 + /** A spare slot for a TX packet. This is treated as an
25 + * extension of the DMA queue. Reads require either
26 + * netfront's tx_lock or the vnic tx_lock; writes require both
27 + * locks */
28 struct sk_buff *tx_skb;
29
30 /** Keep track of fragments of SSR packets */
31 --- sle11-2009-04-09.orig/drivers/xen/sfc_netfront/accel_netfront.c 2009-03-30 16:16:28.000000000 +0200
32 +++ sle11-2009-04-09/drivers/xen/sfc_netfront/accel_netfront.c 2009-04-09 14:42:13.000000000 +0200
33 @@ -65,7 +65,7 @@ static int netfront_accel_netdev_start_x
34 BUG_ON(vnic->net_dev != net_dev);
35 DPRINTK("%s stopping queue\n", __FUNCTION__);
36
37 - /* Netfront's lock protects tx_skb */
38 + /* Need netfront's tx_lock and vnic tx_lock to write tx_skb */
39 spin_lock_irqsave(&np->tx_lock, flags2);
40 BUG_ON(vnic->tx_skb != NULL);
41 vnic->tx_skb = skb;
42 @@ -183,7 +183,7 @@ static int netfront_accel_check_ready(st
43
44 BUG_ON(vnic == NULL);
45
46 - /* This is protected by netfront's lock */
47 + /* Read of tx_skb is protected by netfront's tx_lock */
48 return vnic->tx_skb == NULL;
49 }
50
51 --- sle11-2009-04-09.orig/drivers/xen/sfc_netfront/accel_vi.c 2009-04-09 14:23:18.000000000 +0200
52 +++ sle11-2009-04-09/drivers/xen/sfc_netfront/accel_vi.c 2009-04-09 14:41:38.000000000 +0200
53 @@ -980,39 +980,35 @@ static void netfront_accel_vi_not_busy(n
54 {
55 struct netfront_info *np = ((struct netfront_info *)
56 netdev_priv(vnic->net_dev));
57 - struct sk_buff *skb;
58 int handled;
59 unsigned long flags;
60 -
61 +
62 /*
63 - * TODO if we could safely check tx_skb == NULL and return
64 - * early without taking the lock, that would obviously help
65 - * performance
66 + * We hold the vnic tx_lock which is sufficient to exclude
67 + * writes to tx_skb
68 */
69
70 - /* Take the netfront lock which protects tx_skb. */
71 - spin_lock_irqsave(&np->tx_lock, flags);
72 if (vnic->tx_skb != NULL) {
73 DPRINTK("%s trying to send spare buffer\n", __FUNCTION__);
74
75 - skb = vnic->tx_skb;
76 - vnic->tx_skb = NULL;
77 -
78 - spin_unlock_irqrestore(&np->tx_lock, flags);
79 -
80 - handled = netfront_accel_vi_tx_post(vnic, skb);
81 + handled = netfront_accel_vi_tx_post(vnic, vnic->tx_skb);
82
83 - spin_lock_irqsave(&np->tx_lock, flags);
84 -
85 if (handled != NETFRONT_ACCEL_STATUS_BUSY) {
86 DPRINTK("%s restarting tx\n", __FUNCTION__);
87 +
88 + /* Need netfront tx_lock and vnic tx_lock to
89 + * write tx_skb */
90 + spin_lock_irqsave(&np->tx_lock, flags);
91 +
92 + vnic->tx_skb = NULL;
93 +
94 if (netfront_check_queue_ready(vnic->net_dev)) {
95 netif_wake_queue(vnic->net_dev);
96 NETFRONT_ACCEL_STATS_OP
97 (vnic->stats.queue_wakes++);
98 }
99 - } else {
100 - vnic->tx_skb = skb;
101 + spin_unlock_irqrestore(&np->tx_lock, flags);
102 +
103 }
104
105 /*
106 @@ -1021,7 +1017,6 @@ static void netfront_accel_vi_not_busy(n
107 */
108 BUG_ON(handled == NETFRONT_ACCEL_STATUS_CANT);
109 }
110 - spin_unlock_irqrestore(&np->tx_lock, flags);
111 }
112
113