aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/aoe/aoedev.c
diff options
context:
space:
mode:
authorEd L. Cashin <ecashin@coraid.com>2006-09-20 14:36:49 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-10-18 15:53:50 -0400
commite407a7f6cd143b3ab4eb3d7e1cf882e96b710eb5 (patch)
treea180d2a6ae40b1fe6773c93a24a5c469948fd59d /drivers/block/aoe/aoedev.c
parent2fdc0ea75b26e3009cfdf72e79901e4e16bb99bd (diff)
aoe: zero copy write 1 of 2
Avoid memory copy on writes. (This patch depends on fixes in patch 9 to follow.) Although skb->len should not be set when working with linear skbuffs, the skb->tail pointer maintained by skb_put/skb_trim is not relevant to what happens when the skb_fill_page_desc function is called. This issue was raised without comment in linux-kernel and netdev earlier this month: http://thread.gmane.org/gmane.linux.kernel/446474/ http://thread.gmane.org/gmane.linux.network/45444/ So until there is something analogous to skb_put that works for zero-copy write skbuffs, we will do what the other callers of skb_fill_page_desc are doing. Signed-off-by: "Ed L. Cashin" <ecashin@coraid.com> Acked-by: Alan Cox <alan@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/block/aoe/aoedev.c')
-rw-r--r--drivers/block/aoe/aoedev.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index c7e05ed82512..abf1d3c073e3 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -63,22 +63,32 @@ aoedev_newdev(ulong nframes)
63 struct frame *f, *e; 63 struct frame *f, *e;
64 64
65 d = kzalloc(sizeof *d, GFP_ATOMIC); 65 d = kzalloc(sizeof *d, GFP_ATOMIC);
66 if (d == NULL)
67 return NULL;
68 f = kcalloc(nframes, sizeof *f, GFP_ATOMIC); 66 f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
69 if (f == NULL) { 67 switch (!d || !f) {
70 kfree(d); 68 case 0:
69 d->nframes = nframes;
70 d->frames = f;
71 e = f + nframes;
72 for (; f<e; f++) {
73 f->tag = FREETAG;
74 f->skb = new_skb(ETH_ZLEN);
75 if (!f->skb)
76 break;
77 }
78 if (f == e)
79 break;
80 while (f > d->frames) {
81 f--;
82 dev_kfree_skb(f->skb);
83 }
84 default:
85 if (f)
86 kfree(f);
87 if (d)
88 kfree(d);
71 return NULL; 89 return NULL;
72 } 90 }
73
74 INIT_WORK(&d->work, aoecmd_sleepwork, d); 91 INIT_WORK(&d->work, aoecmd_sleepwork, d);
75
76 d->nframes = nframes;
77 d->frames = f;
78 e = f + nframes;
79 for (; f<e; f++)
80 f->tag = FREETAG;
81
82 spin_lock_init(&d->lock); 92 spin_lock_init(&d->lock);
83 init_timer(&d->timer); 93 init_timer(&d->timer);
84 d->timer.data = (ulong) d; 94 d->timer.data = (ulong) d;
@@ -160,11 +170,19 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
160static void 170static void
161aoedev_freedev(struct aoedev *d) 171aoedev_freedev(struct aoedev *d)
162{ 172{
173 struct frame *f, *e;
174
163 if (d->gd) { 175 if (d->gd) {
164 aoedisk_rm_sysfs(d); 176 aoedisk_rm_sysfs(d);
165 del_gendisk(d->gd); 177 del_gendisk(d->gd);
166 put_disk(d->gd); 178 put_disk(d->gd);
167 } 179 }
180 f = d->frames;
181 e = f + d->nframes;
182 for (; f<e; f++) {
183 skb_shinfo(f->skb)->nr_frags = 0;
184 dev_kfree_skb(f->skb);
185 }
168 kfree(d->frames); 186 kfree(d->frames);
169 if (d->bufpool) 187 if (d->bufpool)
170 mempool_destroy(d->bufpool); 188 mempool_destroy(d->bufpool);