diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/aoe/aoe.h | 9 | ||||
-rw-r--r-- | drivers/block/aoe/aoeblk.c | 8 | ||||
-rw-r--r-- | drivers/block/aoe/aoechr.c | 8 | ||||
-rw-r--r-- | drivers/block/aoe/aoecmd.c | 85 | ||||
-rw-r--r-- | drivers/block/aoe/aoedev.c | 12 | ||||
-rw-r--r-- | drivers/block/aoe/aoemain.c | 1 | ||||
-rw-r--r-- | drivers/block/aoe/aoenet.c | 9 |
7 files changed, 56 insertions, 76 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 | ||
200 | int aoenet_init(void); | 197 | int aoenet_init(void); |
201 | void aoenet_exit(void); | 198 | void aoenet_exit(void); |
202 | void aoenet_xmit(struct sk_buff *); | 199 | void aoenet_xmit(struct sk_buff_head *); |
203 | int is_aoe_netif(struct net_device *ifp); | 200 | int is_aoe_netif(struct net_device *ifp); |
204 | int set_aoe_iflist(const char __user *str, size_t size); | 201 | int 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 0c39782b2660..fd2cf5439a1c 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) | |||
158 | static int | 158 | static int |
159 | aoeblk_make_request(struct request_queue *q, struct bio *bio) | 159 | aoeblk_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 | ||
14 | enum { | 15 | enum { |
@@ -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 2f1746295d06..e33da30be4c4 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -114,29 +114,22 @@ ifrotate(struct aoetgt *t) | |||
114 | static void | 114 | static void |
115 | skb_pool_put(struct aoedev *d, struct sk_buff *skb) | 115 | skb_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 | ||
124 | static struct sk_buff * | 120 | static struct sk_buff * |
125 | skb_pool_get(struct aoedev *d) | 121 | skb_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 | */ |
309 | static struct sk_buff * | 297 | static void |
310 | aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) | 298 | aoecmd_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; | ||
347 | cont: | 330 | cont: |
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 | ||
357 | static void | 336 | static 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 | ||
416 | static int | 391 | static int |
@@ -508,16 +483,15 @@ ata_scnt(unsigned char *packet) { | |||
508 | static void | 483 | static void |
509 | rexmit_timer(ulong vp) | 484 | rexmit_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 */ |
@@ -767,12 +741,12 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector | |||
767 | void | 741 | void |
768 | aoecmd_ata_rsp(struct sk_buff *skb) | 742 | aoecmd_ata_rsp(struct sk_buff *skb) |
769 | { | 743 | { |
744 | struct sk_buff_head queue; | ||
770 | struct aoedev *d; | 745 | struct aoedev *d; |
771 | struct aoe_hdr *hin, *hout; | 746 | struct aoe_hdr *hin, *hout; |
772 | struct aoe_atahdr *ahin, *ahout; | 747 | struct aoe_atahdr *ahin, *ahout; |
773 | struct frame *f; | 748 | struct frame *f; |
774 | struct buf *buf; | 749 | struct buf *buf; |
775 | struct sk_buff *sl; | ||
776 | struct aoetgt *t; | 750 | struct aoetgt *t; |
777 | struct aoeif *ifp; | 751 | struct aoeif *ifp; |
778 | register long n; | 752 | register long n; |
@@ -893,21 +867,21 @@ aoecmd_ata_rsp(struct sk_buff *skb) | |||
893 | 867 | ||
894 | aoecmd_work(d); | 868 | aoecmd_work(d); |
895 | xmit: | 869 | xmit: |
896 | sl = d->sendq_hd; | 870 | __skb_queue_head_init(&queue); |
897 | d->sendq_hd = d->sendq_tl = NULL; | 871 | skb_queue_splice_init(&d->sendq, &queue); |
898 | 872 | ||
899 | spin_unlock_irqrestore(&d->lock, flags); | 873 | spin_unlock_irqrestore(&d->lock, flags); |
900 | aoenet_xmit(sl); | 874 | aoenet_xmit(&queue); |
901 | } | 875 | } |
902 | 876 | ||
903 | void | 877 | void |
904 | aoecmd_cfg(ushort aoemajor, unsigned char aoeminor) | 878 | aoecmd_cfg(ushort aoemajor, unsigned char aoeminor) |
905 | { | 879 | { |
906 | struct sk_buff *sl; | 880 | struct sk_buff_head queue; |
907 | |||
908 | sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL); | ||
909 | 881 | ||
910 | aoenet_xmit(sl); | 882 | __skb_queue_head_init(&queue); |
883 | aoecmd_cfg_pkts(aoemajor, aoeminor, &queue); | ||
884 | aoenet_xmit(&queue); | ||
911 | } | 885 | } |
912 | 886 | ||
913 | struct sk_buff * | 887 | struct sk_buff * |
@@ -1076,7 +1050,12 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
1076 | 1050 | ||
1077 | spin_unlock_irqrestore(&d->lock, flags); | 1051 | spin_unlock_irqrestore(&d->lock, flags); |
1078 | 1052 | ||
1079 | aoenet_xmit(sl); | 1053 | if (sl) { |
1054 | struct sk_buff_head queue; | ||
1055 | __skb_queue_head_init(&queue); | ||
1056 | __skb_queue_tail(&queue, sl); | ||
1057 | aoenet_xmit(&queue); | ||
1058 | } | ||
1080 | } | 1059 | } |
1081 | 1060 | ||
1082 | void | 1061 | void |
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index a1d813ab0d6b..75a610adf515 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c | |||
@@ -188,14 +188,12 @@ skbfree(struct sk_buff *skb) | |||
188 | static void | 188 | static void |
189 | skbpoolfree(struct aoedev *d) | 189 | skbpoolfree(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 | ||
12 | MODULE_LICENSE("GPL"); | 13 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index 0c81ca731287..8fb26030eba8 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c | |||
@@ -95,15 +95,12 @@ mac_addr(char addr[6]) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | void | 97 | void |
98 | aoenet_xmit(struct sk_buff *sl) | 98 | aoenet_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; | ||
104 | skb->next = skb->prev = NULL; | ||
105 | dev_queue_xmit(skb); | 103 | dev_queue_xmit(skb); |
106 | } | ||
107 | } | 104 | } |
108 | 105 | ||
109 | /* | 106 | /* |