]> git.openfabrics.org - ~shefty/rdma-dev.git/blob - drivers/block/aoe/aoedev.c
aoe: commands in retransmit queue use new destination on failure
[~shefty/rdma-dev.git] / drivers / block / aoe / aoedev.c
1 /* Copyright (c) 2012 Coraid, Inc.  See COPYING for GPL terms. */
2 /*
3  * aoedev.c
4  * AoE device utility functions; maintains device list.
5  */
6
7 #include <linux/hdreg.h>
8 #include <linux/blkdev.h>
9 #include <linux/netdevice.h>
10 #include <linux/delay.h>
11 #include <linux/slab.h>
12 #include <linux/bitmap.h>
13 #include <linux/kdev_t.h>
14 #include <linux/moduleparam.h>
15 #include "aoe.h"
16
17 static void dummy_timer(ulong);
18 static void aoedev_freedev(struct aoedev *);
19 static void freetgt(struct aoedev *d, struct aoetgt *t);
20 static void skbpoolfree(struct aoedev *d);
21
22 static int aoe_dyndevs = 1;
23 module_param(aoe_dyndevs, int, 0644);
24 MODULE_PARM_DESC(aoe_dyndevs, "Use dynamic minor numbers for devices.");
25
26 static struct aoedev *devlist;
27 static DEFINE_SPINLOCK(devlist_lock);
28
29 /* Because some systems will have one, many, or no
30  *   - partitions,
31  *   - slots per shelf,
32  *   - or shelves,
33  * we need some flexibility in the way the minor numbers
34  * are allocated.  So they are dynamic.
35  */
36 #define N_DEVS ((1U<<MINORBITS)/AOE_PARTITIONS)
37
38 static DEFINE_SPINLOCK(used_minors_lock);
39 static DECLARE_BITMAP(used_minors, N_DEVS);
40
41 static int
42 minor_get_dyn(ulong *sysminor)
43 {
44         ulong flags;
45         ulong n;
46         int error = 0;
47
48         spin_lock_irqsave(&used_minors_lock, flags);
49         n = find_first_zero_bit(used_minors, N_DEVS);
50         if (n < N_DEVS)
51                 set_bit(n, used_minors);
52         else
53                 error = -1;
54         spin_unlock_irqrestore(&used_minors_lock, flags);
55
56         *sysminor = n * AOE_PARTITIONS;
57         return error;
58 }
59
60 static int
61 minor_get_static(ulong *sysminor, ulong aoemaj, int aoemin)
62 {
63         ulong flags;
64         ulong n;
65         int error = 0;
66         enum {
67                 /* for backwards compatibility when !aoe_dyndevs,
68                  * a static number of supported slots per shelf */
69                 NPERSHELF = 16,
70         };
71
72         n = aoemaj * NPERSHELF + aoemin;
73         if (aoemin >= NPERSHELF || n >= N_DEVS) {
74                 pr_err("aoe: %s with e%ld.%d\n",
75                         "cannot use static minor device numbers",
76                         aoemaj, aoemin);
77                 error = -1;
78         } else {
79                 spin_lock_irqsave(&used_minors_lock, flags);
80                 if (test_bit(n, used_minors)) {
81                         pr_err("aoe: %s %lu\n",
82                                 "existing device already has static minor number",
83                                 n);
84                         error = -1;
85                 } else
86                         set_bit(n, used_minors);
87                 spin_unlock_irqrestore(&used_minors_lock, flags);
88         }
89
90         *sysminor = n;
91         return error;
92 }
93
94 static int
95 minor_get(ulong *sysminor, ulong aoemaj, int aoemin)
96 {
97         if (aoe_dyndevs)
98                 return minor_get_dyn(sysminor);
99         else
100                 return minor_get_static(sysminor, aoemaj, aoemin);
101 }
102
103 static void
104 minor_free(ulong minor)
105 {
106         ulong flags;
107
108         minor /= AOE_PARTITIONS;
109         BUG_ON(minor >= N_DEVS);
110
111         spin_lock_irqsave(&used_minors_lock, flags);
112         BUG_ON(!test_bit(minor, used_minors));
113         clear_bit(minor, used_minors);
114         spin_unlock_irqrestore(&used_minors_lock, flags);
115 }
116
117 /*
118  * Users who grab a pointer to the device with aoedev_by_aoeaddr
119  * automatically get a reference count and must be responsible
120  * for performing a aoedev_put.  With the addition of async
121  * kthread processing I'm no longer confident that we can
122  * guarantee consistency in the face of device flushes.
123  *
124  * For the time being, we only bother to add extra references for
125  * frames sitting on the iocq.  When the kthreads finish processing
126  * these frames, they will aoedev_put the device.
127  */
128
129 void
130 aoedev_put(struct aoedev *d)
131 {
132         ulong flags;
133
134         spin_lock_irqsave(&devlist_lock, flags);
135         d->ref--;
136         spin_unlock_irqrestore(&devlist_lock, flags);
137 }
138
139 static void
140 dummy_timer(ulong vp)
141 {
142         struct aoedev *d;
143
144         d = (struct aoedev *)vp;
145         if (d->flags & DEVFL_TKILL)
146                 return;
147         d->timer.expires = jiffies + HZ;
148         add_timer(&d->timer);
149 }
150
151 static void
152 aoe_failip(struct aoedev *d)
153 {
154         struct request *rq;
155         struct bio *bio;
156         unsigned long n;
157
158         aoe_failbuf(d, d->ip.buf);
159
160         rq = d->ip.rq;
161         if (rq == NULL)
162                 return;
163         while ((bio = d->ip.nxbio)) {
164                 clear_bit(BIO_UPTODATE, &bio->bi_flags);
165                 d->ip.nxbio = bio->bi_next;
166                 n = (unsigned long) rq->special;
167                 rq->special = (void *) --n;
168         }
169         if ((unsigned long) rq->special == 0)
170                 aoe_end_request(d, rq, 0);
171 }
172
173 static void
174 downdev_frame(struct list_head *pos)
175 {
176         struct frame *f;
177
178         f = list_entry(pos, struct frame, head);
179         list_del(pos);
180         if (f->buf) {
181                 f->buf->nframesout--;
182                 aoe_failbuf(f->t->d, f->buf);
183         }
184         aoe_freetframe(f);
185 }
186
187 void
188 aoedev_downdev(struct aoedev *d)
189 {
190         struct aoetgt *t, **tt, **te;
191         struct list_head *head, *pos, *nx;
192         struct request *rq;
193         int i;
194
195         d->flags &= ~DEVFL_UP;
196
197         /* clean out active and to-be-retransmitted buffers */
198         for (i = 0; i < NFACTIVE; i++) {
199                 head = &d->factive[i];
200                 list_for_each_safe(pos, nx, head)
201                         downdev_frame(pos);
202         }
203         head = &d->rexmitq;
204         list_for_each_safe(pos, nx, head)
205                 downdev_frame(pos);
206
207         /* reset window dressings */
208         tt = d->targets;
209         te = tt + NTARGETS;
210         for (; tt < te && (t = *tt); tt++) {
211                 aoecmd_wreset(t);
212                 t->nout = 0;
213         }
214
215         /* clean out the in-process request (if any) */
216         aoe_failip(d);
217         d->htgt = NULL;
218
219         /* fast fail all pending I/O */
220         if (d->blkq) {
221                 while ((rq = blk_peek_request(d->blkq))) {
222                         blk_start_request(rq);
223                         aoe_end_request(d, rq, 1);
224                 }
225         }
226
227         if (d->gd)
228                 set_capacity(d->gd, 0);
229 }
230
231 static void
232 aoedev_freedev(struct aoedev *d)
233 {
234         struct aoetgt **t, **e;
235
236         cancel_work_sync(&d->work);
237         if (d->gd) {
238                 aoedisk_rm_sysfs(d);
239                 del_gendisk(d->gd);
240                 put_disk(d->gd);
241                 blk_cleanup_queue(d->blkq);
242         }
243         t = d->targets;
244         e = t + NTARGETS;
245         for (; t < e && *t; t++)
246                 freetgt(d, *t);
247         if (d->bufpool)
248                 mempool_destroy(d->bufpool);
249         skbpoolfree(d);
250         minor_free(d->sysminor);
251         kfree(d);
252 }
253
254 /* return whether the user asked for this particular
255  * device to be flushed
256  */
257 static int
258 user_req(char *s, size_t slen, struct aoedev *d)
259 {
260         char *p;
261         size_t lim;
262
263         if (!d->gd)
264                 return 0;
265         p = strrchr(d->gd->disk_name, '/');
266         if (!p)
267                 p = d->gd->disk_name;
268         else
269                 p += 1;
270         lim = sizeof(d->gd->disk_name);
271         lim -= p - d->gd->disk_name;
272         if (slen < lim)
273                 lim = slen;
274
275         return !strncmp(s, p, lim);
276 }
277
278 int
279 aoedev_flush(const char __user *str, size_t cnt)
280 {
281         ulong flags;
282         struct aoedev *d, **dd;
283         struct aoedev *rmd = NULL;
284         char buf[16];
285         int all = 0;
286         int specified = 0;      /* flush a specific device */
287
288         if (cnt >= 3) {
289                 if (cnt > sizeof buf)
290                         cnt = sizeof buf;
291                 if (copy_from_user(buf, str, cnt))
292                         return -EFAULT;
293                 all = !strncmp(buf, "all", 3);
294                 if (!all)
295                         specified = 1;
296         }
297
298         spin_lock_irqsave(&devlist_lock, flags);
299         dd = &devlist;
300         while ((d = *dd)) {
301                 spin_lock(&d->lock);
302                 if (specified) {
303                         if (!user_req(buf, cnt, d))
304                                 goto skip;
305                 } else if ((!all && (d->flags & DEVFL_UP))
306                 || (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
307                 || d->nopen
308                 || d->ref)
309                         goto skip;
310
311                 *dd = d->next;
312                 aoedev_downdev(d);
313                 d->flags |= DEVFL_TKILL;
314                 spin_unlock(&d->lock);
315                 d->next = rmd;
316                 rmd = d;
317                 continue;
318 skip:
319                 spin_unlock(&d->lock);
320                 dd = &d->next;
321         }
322         spin_unlock_irqrestore(&devlist_lock, flags);
323         while ((d = rmd)) {
324                 rmd = d->next;
325                 del_timer_sync(&d->timer);
326                 aoedev_freedev(d);      /* must be able to sleep */
327         }
328         return 0;
329 }
330
331 /* This has been confirmed to occur once with Tms=3*1000 due to the
332  * driver changing link and not processing its transmit ring.  The
333  * problem is hard enough to solve by returning an error that I'm
334  * still punting on "solving" this.
335  */
336 static void
337 skbfree(struct sk_buff *skb)
338 {
339         enum { Sms = 250, Tms = 30 * 1000};
340         int i = Tms / Sms;
341
342         if (skb == NULL)
343                 return;
344         while (atomic_read(&skb_shinfo(skb)->dataref) != 1 && i-- > 0)
345                 msleep(Sms);
346         if (i < 0) {
347                 printk(KERN_ERR
348                         "aoe: %s holds ref: %s\n",
349                         skb->dev ? skb->dev->name : "netif",
350                         "cannot free skb -- memory leaked.");
351                 return;
352         }
353         skb->truesize -= skb->data_len;
354         skb_shinfo(skb)->nr_frags = skb->data_len = 0;
355         skb_trim(skb, 0);
356         dev_kfree_skb(skb);
357 }
358
359 static void
360 skbpoolfree(struct aoedev *d)
361 {
362         struct sk_buff *skb, *tmp;
363
364         skb_queue_walk_safe(&d->skbpool, skb, tmp)
365                 skbfree(skb);
366
367         __skb_queue_head_init(&d->skbpool);
368 }
369
370 /* find it or allocate it */
371 struct aoedev *
372 aoedev_by_aoeaddr(ulong maj, int min, int do_alloc)
373 {
374         struct aoedev *d;
375         int i;
376         ulong flags;
377         ulong sysminor;
378
379         spin_lock_irqsave(&devlist_lock, flags);
380
381         for (d=devlist; d; d=d->next)
382                 if (d->aoemajor == maj && d->aoeminor == min) {
383                         d->ref++;
384                         break;
385                 }
386         if (d || !do_alloc || minor_get(&sysminor, maj, min) < 0)
387                 goto out;
388         d = kcalloc(1, sizeof *d, GFP_ATOMIC);
389         if (!d)
390                 goto out;
391         INIT_WORK(&d->work, aoecmd_sleepwork);
392         spin_lock_init(&d->lock);
393         skb_queue_head_init(&d->skbpool);
394         init_timer(&d->timer);
395         d->timer.data = (ulong) d;
396         d->timer.function = dummy_timer;
397         d->timer.expires = jiffies + HZ;
398         add_timer(&d->timer);
399         d->bufpool = NULL;      /* defer to aoeblk_gdalloc */
400         d->tgt = d->targets;
401         d->ref = 1;
402         for (i = 0; i < NFACTIVE; i++)
403                 INIT_LIST_HEAD(&d->factive[i]);
404         INIT_LIST_HEAD(&d->rexmitq);
405         d->sysminor = sysminor;
406         d->aoemajor = maj;
407         d->aoeminor = min;
408         d->rttavg = RTTAVG_INIT;
409         d->rttdev = RTTDEV_INIT;
410         d->next = devlist;
411         devlist = d;
412  out:
413         spin_unlock_irqrestore(&devlist_lock, flags);
414         return d;
415 }
416
417 static void
418 freetgt(struct aoedev *d, struct aoetgt *t)
419 {
420         struct frame *f;
421         struct list_head *pos, *nx, *head;
422         struct aoeif *ifp;
423
424         for (ifp = t->ifs; ifp < &t->ifs[NAOEIFS]; ++ifp) {
425                 if (!ifp->nd)
426                         break;
427                 dev_put(ifp->nd);
428         }
429
430         head = &t->ffree;
431         list_for_each_safe(pos, nx, head) {
432                 list_del(pos);
433                 f = list_entry(pos, struct frame, head);
434                 skbfree(f->skb);
435                 kfree(f);
436         }
437         kfree(t);
438 }
439
440 void
441 aoedev_exit(void)
442 {
443         struct aoedev *d;
444         ulong flags;
445
446         aoe_flush_iocq();
447         while ((d = devlist)) {
448                 devlist = d->next;
449
450                 spin_lock_irqsave(&d->lock, flags);
451                 aoedev_downdev(d);
452                 d->flags |= DEVFL_TKILL;
453                 spin_unlock_irqrestore(&d->lock, flags);
454
455                 del_timer_sync(&d->timer);
456                 aoedev_freedev(d);
457         }
458 }
459
460 int __init
461 aoedev_init(void)
462 {
463         return 0;
464 }