aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/aoe
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/aoe')
-rw-r--r--drivers/block/aoe/aoe.h9
-rw-r--r--drivers/block/aoe/aoeblk.c8
-rw-r--r--drivers/block/aoe/aoechr.c8
-rw-r--r--drivers/block/aoe/aoecmd.c85
-rw-r--r--drivers/block/aoe/aoedev.c12
-rw-r--r--drivers/block/aoe/aoemain.c1
-rw-r--r--drivers/block/aoe/aoenet.c9
7 files changed, 57 insertions, 75 deletions
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 5b4c6e649c11..93f3690396a5 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -159,11 +159,8 @@ struct aoedev {
159 sector_t ssize; 159 sector_t ssize;
160 struct timer_list timer; 160 struct timer_list timer;
161 spinlock_t lock; 161 spinlock_t lock;
162 struct sk_buff *sendq_hd; /* packets needing to be sent, list head */ 162 struct sk_buff_head sendq;
163 struct sk_buff *sendq_tl; 163 struct sk_buff_head skbpool;
164 struct sk_buff *skbpool_hd;
165 struct sk_buff *skbpool_tl;
166 int nskbpool;
167 mempool_t *bufpool; /* for deadlock-free Buf allocation */ 164 mempool_t *bufpool; /* for deadlock-free Buf allocation */
168 struct list_head bufq; /* queue of bios to work on */ 165 struct list_head bufq; /* queue of bios to work on */
169 struct buf *inprocess; /* the one we're currently working on */ 166 struct buf *inprocess; /* the one we're currently working on */
@@ -199,7 +196,7 @@ int aoedev_flush(const char __user *str, size_t size);
199 196
200int aoenet_init(void); 197int aoenet_init(void);
201void aoenet_exit(void); 198void aoenet_exit(void);
202void aoenet_xmit(struct sk_buff *); 199void aoenet_xmit(struct sk_buff_head *);
203int is_aoe_netif(struct net_device *ifp); 200int is_aoe_netif(struct net_device *ifp);
204int set_aoe_iflist(const char __user *str, size_t size); 201int set_aoe_iflist(const char __user *str, size_t size);
205 202
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index aa69556c3485..b82654e883a7 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -158,9 +158,9 @@ aoeblk_release(struct inode *inode, struct file *filp)
158static int 158static int
159aoeblk_make_request(struct request_queue *q, struct bio *bio) 159aoeblk_make_request(struct request_queue *q, struct bio *bio)
160{ 160{
161 struct sk_buff_head queue;
161 struct aoedev *d; 162 struct aoedev *d;
162 struct buf *buf; 163 struct buf *buf;
163 struct sk_buff *sl;
164 ulong flags; 164 ulong flags;
165 165
166 blk_queue_bounce(q, &bio); 166 blk_queue_bounce(q, &bio);
@@ -213,11 +213,11 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio)
213 list_add_tail(&buf->bufs, &d->bufq); 213 list_add_tail(&buf->bufs, &d->bufq);
214 214
215 aoecmd_work(d); 215 aoecmd_work(d);
216 sl = d->sendq_hd; 216 __skb_queue_head_init(&queue);
217 d->sendq_hd = d->sendq_tl = NULL; 217 skb_queue_splice_init(&d->sendq, &queue);
218 218
219 spin_unlock_irqrestore(&d->lock, flags); 219 spin_unlock_irqrestore(&d->lock, flags);
220 aoenet_xmit(sl); 220 aoenet_xmit(&queue);
221 221
222 return 0; 222 return 0;
223} 223}
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 181ebb85f0be..1f56d2c5b7fc 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -9,6 +9,7 @@
9#include <linux/completion.h> 9#include <linux/completion.h>
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/smp_lock.h> 11#include <linux/smp_lock.h>
12#include <linux/skbuff.h>
12#include "aoe.h" 13#include "aoe.h"
13 14
14enum { 15enum {
@@ -103,7 +104,12 @@ loop:
103 spin_lock_irqsave(&d->lock, flags); 104 spin_lock_irqsave(&d->lock, flags);
104 goto loop; 105 goto loop;
105 } 106 }
106 aoenet_xmit(skb); 107 if (skb) {
108 struct sk_buff_head queue;
109 __skb_queue_head_init(&queue);
110 __skb_queue_tail(&queue, skb);
111 aoenet_xmit(&queue);
112 }
107 aoecmd_cfg(major, minor); 113 aoecmd_cfg(major, minor);
108 return 0; 114 return 0;
109} 115}
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 961d29a53cab..71ff78c9e4d6 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -114,29 +114,22 @@ ifrotate(struct aoetgt *t)
114static void 114static void
115skb_pool_put(struct aoedev *d, struct sk_buff *skb) 115skb_pool_put(struct aoedev *d, struct sk_buff *skb)
116{ 116{
117 if (!d->skbpool_hd) 117 __skb_queue_tail(&d->skbpool, skb);
118 d->skbpool_hd = skb;
119 else
120 d->skbpool_tl->next = skb;
121 d->skbpool_tl = skb;
122} 118}
123 119
124static struct sk_buff * 120static struct sk_buff *
125skb_pool_get(struct aoedev *d) 121skb_pool_get(struct aoedev *d)
126{ 122{
127 struct sk_buff *skb; 123 struct sk_buff *skb = skb_peek(&d->skbpool);
128 124
129 skb = d->skbpool_hd;
130 if (skb && atomic_read(&skb_shinfo(skb)->dataref) == 1) { 125 if (skb && atomic_read(&skb_shinfo(skb)->dataref) == 1) {
131 d->skbpool_hd = skb->next; 126 __skb_unlink(skb, &d->skbpool);
132 skb->next = NULL;
133 return skb; 127 return skb;
134 } 128 }
135 if (d->nskbpool < NSKBPOOLMAX 129 if (skb_queue_len(&d->skbpool) < NSKBPOOLMAX &&
136 && (skb = new_skb(ETH_ZLEN))) { 130 (skb = new_skb(ETH_ZLEN)))
137 d->nskbpool++;
138 return skb; 131 return skb;
139 } 132
140 return NULL; 133 return NULL;
141} 134}
142 135
@@ -293,29 +286,22 @@ aoecmd_ata_rw(struct aoedev *d)
293 286
294 skb->dev = t->ifp->nd; 287 skb->dev = t->ifp->nd;
295 skb = skb_clone(skb, GFP_ATOMIC); 288 skb = skb_clone(skb, GFP_ATOMIC);
296 if (skb) { 289 if (skb)
297 if (d->sendq_hd) 290 __skb_queue_tail(&d->sendq, skb);
298 d->sendq_tl->next = skb;
299 else
300 d->sendq_hd = skb;
301 d->sendq_tl = skb;
302 }
303 return 1; 291 return 1;
304} 292}
305 293
306/* some callers cannot sleep, and they can call this function, 294/* some callers cannot sleep, and they can call this function,
307 * transmitting the packets later, when interrupts are on 295 * transmitting the packets later, when interrupts are on
308 */ 296 */
309static struct sk_buff * 297static void
310aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) 298aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *queue)
311{ 299{
312 struct aoe_hdr *h; 300 struct aoe_hdr *h;
313 struct aoe_cfghdr *ch; 301 struct aoe_cfghdr *ch;
314 struct sk_buff *skb, *sl, *sl_tail; 302 struct sk_buff *skb;
315 struct net_device *ifp; 303 struct net_device *ifp;
316 304
317 sl = sl_tail = NULL;
318
319 read_lock(&dev_base_lock); 305 read_lock(&dev_base_lock);
320 for_each_netdev(&init_net, ifp) { 306 for_each_netdev(&init_net, ifp) {
321 dev_hold(ifp); 307 dev_hold(ifp);
@@ -329,8 +315,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
329 } 315 }
330 skb_put(skb, sizeof *h + sizeof *ch); 316 skb_put(skb, sizeof *h + sizeof *ch);
331 skb->dev = ifp; 317 skb->dev = ifp;
332 if (sl_tail == NULL) 318 __skb_queue_tail(queue, skb);
333 sl_tail = skb;
334 h = (struct aoe_hdr *) skb_mac_header(skb); 319 h = (struct aoe_hdr *) skb_mac_header(skb);
335 memset(h, 0, sizeof *h + sizeof *ch); 320 memset(h, 0, sizeof *h + sizeof *ch);
336 321
@@ -342,16 +327,10 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
342 h->minor = aoeminor; 327 h->minor = aoeminor;
343 h->cmd = AOECMD_CFG; 328 h->cmd = AOECMD_CFG;
344 329
345 skb->next = sl;
346 sl = skb;
347cont: 330cont:
348 dev_put(ifp); 331 dev_put(ifp);
349 } 332 }
350 read_unlock(&dev_base_lock); 333 read_unlock(&dev_base_lock);
351
352 if (tail != NULL)
353 *tail = sl_tail;
354 return sl;
355} 334}
356 335
357static void 336static void
@@ -406,11 +385,7 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
406 skb = skb_clone(skb, GFP_ATOMIC); 385 skb = skb_clone(skb, GFP_ATOMIC);
407 if (skb == NULL) 386 if (skb == NULL)
408 return; 387 return;
409 if (d->sendq_hd) 388 __skb_queue_tail(&d->sendq, skb);
410 d->sendq_tl->next = skb;
411 else
412 d->sendq_hd = skb;
413 d->sendq_tl = skb;
414} 389}
415 390
416static int 391static int
@@ -508,16 +483,15 @@ ata_scnt(unsigned char *packet) {
508static void 483static void
509rexmit_timer(ulong vp) 484rexmit_timer(ulong vp)
510{ 485{
486 struct sk_buff_head queue;
511 struct aoedev *d; 487 struct aoedev *d;
512 struct aoetgt *t, **tt, **te; 488 struct aoetgt *t, **tt, **te;
513 struct aoeif *ifp; 489 struct aoeif *ifp;
514 struct frame *f, *e; 490 struct frame *f, *e;
515 struct sk_buff *sl;
516 register long timeout; 491 register long timeout;
517 ulong flags, n; 492 ulong flags, n;
518 493
519 d = (struct aoedev *) vp; 494 d = (struct aoedev *) vp;
520 sl = NULL;
521 495
522 /* timeout is always ~150% of the moving average */ 496 /* timeout is always ~150% of the moving average */
523 timeout = d->rttavg; 497 timeout = d->rttavg;
@@ -589,7 +563,7 @@ rexmit_timer(ulong vp)
589 } 563 }
590 } 564 }
591 565
592 if (d->sendq_hd) { 566 if (!skb_queue_empty(&d->sendq)) {
593 n = d->rttavg <<= 1; 567 n = d->rttavg <<= 1;
594 if (n > MAXTIMER) 568 if (n > MAXTIMER)
595 d->rttavg = MAXTIMER; 569 d->rttavg = MAXTIMER;
@@ -600,15 +574,15 @@ rexmit_timer(ulong vp)
600 aoecmd_work(d); 574 aoecmd_work(d);
601 } 575 }
602 576
603 sl = d->sendq_hd; 577 __skb_queue_head_init(&queue);
604 d->sendq_hd = d->sendq_tl = NULL; 578 skb_queue_splice_init(&d->sendq, &queue);
605 579
606 d->timer.expires = jiffies + TIMERTICK; 580 d->timer.expires = jiffies + TIMERTICK;
607 add_timer(&d->timer); 581 add_timer(&d->timer);
608 582
609 spin_unlock_irqrestore(&d->lock, flags); 583 spin_unlock_irqrestore(&d->lock, flags);
610 584
611 aoenet_xmit(sl); 585 aoenet_xmit(&queue);
612} 586}
613 587
614/* enters with d->lock held */ 588/* enters with d->lock held */
@@ -772,12 +746,12 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
772void 746void
773aoecmd_ata_rsp(struct sk_buff *skb) 747aoecmd_ata_rsp(struct sk_buff *skb)
774{ 748{
749 struct sk_buff_head queue;
775 struct aoedev *d; 750 struct aoedev *d;
776 struct aoe_hdr *hin, *hout; 751 struct aoe_hdr *hin, *hout;
777 struct aoe_atahdr *ahin, *ahout; 752 struct aoe_atahdr *ahin, *ahout;
778 struct frame *f; 753 struct frame *f;
779 struct buf *buf; 754 struct buf *buf;
780 struct sk_buff *sl;
781 struct aoetgt *t; 755 struct aoetgt *t;
782 struct aoeif *ifp; 756 struct aoeif *ifp;
783 register long n; 757 register long n;
@@ -898,21 +872,21 @@ aoecmd_ata_rsp(struct sk_buff *skb)
898 872
899 aoecmd_work(d); 873 aoecmd_work(d);
900xmit: 874xmit:
901 sl = d->sendq_hd; 875 __skb_queue_head_init(&queue);
902 d->sendq_hd = d->sendq_tl = NULL; 876 skb_queue_splice_init(&d->sendq, &queue);
903 877
904 spin_unlock_irqrestore(&d->lock, flags); 878 spin_unlock_irqrestore(&d->lock, flags);
905 aoenet_xmit(sl); 879 aoenet_xmit(&queue);
906} 880}
907 881
908void 882void
909aoecmd_cfg(ushort aoemajor, unsigned char aoeminor) 883aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
910{ 884{
911 struct sk_buff *sl; 885 struct sk_buff_head queue;
912
913 sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL);
914 886
915 aoenet_xmit(sl); 887 __skb_queue_head_init(&queue);
888 aoecmd_cfg_pkts(aoemajor, aoeminor, &queue);
889 aoenet_xmit(&queue);
916} 890}
917 891
918struct sk_buff * 892struct sk_buff *
@@ -1081,7 +1055,12 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
1081 1055
1082 spin_unlock_irqrestore(&d->lock, flags); 1056 spin_unlock_irqrestore(&d->lock, flags);
1083 1057
1084 aoenet_xmit(sl); 1058 if (sl) {
1059 struct sk_buff_head queue;
1060 __skb_queue_head_init(&queue);
1061 __skb_queue_tail(&queue, sl);
1062 aoenet_xmit(&queue);
1063 }
1085} 1064}
1086 1065
1087void 1066void
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index 6a8038d115b5..cc250577d405 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -188,14 +188,12 @@ skbfree(struct sk_buff *skb)
188static void 188static void
189skbpoolfree(struct aoedev *d) 189skbpoolfree(struct aoedev *d)
190{ 190{
191 struct sk_buff *skb; 191 struct sk_buff *skb, *tmp;
192 192
193 while ((skb = d->skbpool_hd)) { 193 skb_queue_walk_safe(&d->skbpool, skb, tmp)
194 d->skbpool_hd = skb->next;
195 skb->next = NULL;
196 skbfree(skb); 194 skbfree(skb);
197 } 195
198 d->skbpool_tl = NULL; 196 __skb_queue_head_init(&d->skbpool);
199} 197}
200 198
201/* find it or malloc it */ 199/* find it or malloc it */
@@ -217,6 +215,8 @@ aoedev_by_sysminor_m(ulong sysminor)
217 goto out; 215 goto out;
218 INIT_WORK(&d->work, aoecmd_sleepwork); 216 INIT_WORK(&d->work, aoecmd_sleepwork);
219 spin_lock_init(&d->lock); 217 spin_lock_init(&d->lock);
218 skb_queue_head_init(&d->sendq);
219 skb_queue_head_init(&d->skbpool);
220 init_timer(&d->timer); 220 init_timer(&d->timer);
221 d->timer.data = (ulong) d; 221 d->timer.data = (ulong) d;
222 d->timer.function = dummy_timer; 222 d->timer.function = dummy_timer;
diff --git a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c
index 7b15a5e9cec0..7f83ad90e76f 100644
--- a/drivers/block/aoe/aoemain.c
+++ b/drivers/block/aoe/aoemain.c
@@ -7,6 +7,7 @@
7#include <linux/hdreg.h> 7#include <linux/hdreg.h>
8#include <linux/blkdev.h> 8#include <linux/blkdev.h>
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/skbuff.h>
10#include "aoe.h" 11#include "aoe.h"
11 12
12MODULE_LICENSE("GPL"); 13MODULE_LICENSE("GPL");
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index 0c81ca731287..9157d64270cb 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -95,13 +95,12 @@ mac_addr(char addr[6])
95} 95}
96 96
97void 97void
98aoenet_xmit(struct sk_buff *sl) 98aoenet_xmit(struct sk_buff_head *queue)
99{ 99{
100 struct sk_buff *skb; 100 struct sk_buff *skb, *tmp;
101 101
102 while ((skb = sl)) { 102 skb_queue_walk_safe(queue, skb, tmp) {
103 sl = sl->next; 103 __skb_unlink(skb, queue);
104 skb->next = skb->prev = NULL;
105 dev_queue_xmit(skb); 104 dev_queue_xmit(skb);
106 } 105 }
107} 106}