]> git.openfabrics.org - ~shefty/rdma-dev.git/blob - drivers/block/aoe/aoedev.c
aoe: support the forgetting (flushing) of a user-specified AoE target
[~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 void
174 aoedev_downdev(struct aoedev *d)
175 {
176         struct aoetgt *t, **tt, **te;
177         struct frame *f;
178         struct list_head *head, *pos, *nx;
179         struct request *rq;
180         int i;
181
182         d->flags &= ~DEVFL_UP;
183
184         /* clean out active buffers */
185         for (i = 0; i < NFACTIVE; i++) {
186                 head = &d->factive[i];
187                 list_for_each_safe(pos, nx, head) {
188                         f = list_entry(pos, struct frame, head);
189                         list_del(pos);
190                         if (f->buf) {
191                                 f->buf->nframesout--;
192                                 aoe_failbuf(d, f->buf);
193                         }
194                         aoe_freetframe(f);
195                 }
196         }
197         /* reset window dressings */
198         tt = d->targets;
199         te = tt + NTARGETS;
200         for (; tt < te && (t = *tt); tt++) {
201                 t->maxout = t->nframes;
202                 t->nout = 0;
203         }
204
205         /* clean out the in-process request (if any) */
206         aoe_failip(d);
207         d->htgt = NULL;
208
209         /* fast fail all pending I/O */
210         if (d->blkq) {
211                 while ((rq = blk_peek_request(d->blkq))) {
212                         blk_start_request(rq);
213                         aoe_end_request(d, rq, 1);
214                 }
215         }
216
217         if (d->gd)
218                 set_capacity(d->gd, 0);
219 }
220
221 static void
222 aoedev_freedev(struct aoedev *d)
223 {
224         struct aoetgt **t, **e;
225
226         cancel_work_sync(&d->work);
227         if (d->gd) {
228                 aoedisk_rm_sysfs(d);
229                 del_gendisk(d->gd);
230                 put_disk(d->gd);
231                 blk_cleanup_queue(d->blkq);
232         }
233         t = d->targets;
234         e = t + NTARGETS;
235         for (; t < e && *t; t++)
236                 freetgt(d, *t);
237         if (d->bufpool)
238                 mempool_destroy(d->bufpool);
239         skbpoolfree(d);
240         minor_free(d->sysminor);
241         kfree(d);
242 }
243
244 /* return whether the user asked for this particular
245  * device to be flushed
246  */
247 static int
248 user_req(char *s, size_t slen, struct aoedev *d)
249 {
250         char *p;
251         size_t lim;
252
253         if (!d->gd)
254                 return 0;
255         p = strrchr(d->gd->disk_name, '/');
256         if (!p)
257                 p = d->gd->disk_name;
258         else
259                 p += 1;
260         lim = sizeof(d->gd->disk_name);
261         lim -= p - d->gd->disk_name;
262         if (slen < lim)
263                 lim = slen;
264
265         return !strncmp(s, p, lim);
266 }
267
268 int
269 aoedev_flush(const char __user *str, size_t cnt)
270 {
271         ulong flags;
272         struct aoedev *d, **dd;
273         struct aoedev *rmd = NULL;
274         char buf[16];
275         int all = 0;
276         int specified = 0;      /* flush a specific device */
277
278         if (cnt >= 3) {
279                 if (cnt > sizeof buf)
280                         cnt = sizeof buf;
281                 if (copy_from_user(buf, str, cnt))
282                         return -EFAULT;
283                 all = !strncmp(buf, "all", 3);
284                 if (!all)
285                         specified = 1;
286         }
287
288         spin_lock_irqsave(&devlist_lock, flags);
289         dd = &devlist;
290         while ((d = *dd)) {
291                 spin_lock(&d->lock);
292                 if (specified) {
293                         if (!user_req(buf, cnt, d))
294                                 goto skip;
295                 } else if ((!all && (d->flags & DEVFL_UP))
296                 || (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
297                 || d->nopen
298                 || d->ref)
299                         goto skip;
300
301                 *dd = d->next;
302                 aoedev_downdev(d);
303                 d->flags |= DEVFL_TKILL;
304                 spin_unlock(&d->lock);
305                 d->next = rmd;
306                 rmd = d;
307                 continue;
308 skip:
309                 spin_unlock(&d->lock);
310                 dd = &d->next;
311         }
312         spin_unlock_irqrestore(&devlist_lock, flags);
313         while ((d = rmd)) {
314                 rmd = d->next;
315                 del_timer_sync(&d->timer);
316                 aoedev_freedev(d);      /* must be able to sleep */
317         }
318         return 0;
319 }
320
321 /* This has been confirmed to occur once with Tms=3*1000 due to the
322  * driver changing link and not processing its transmit ring.  The
323  * problem is hard enough to solve by returning an error that I'm
324  * still punting on "solving" this.
325  */
326 static void
327 skbfree(struct sk_buff *skb)
328 {
329         enum { Sms = 250, Tms = 30 * 1000};
330         int i = Tms / Sms;
331
332         if (skb == NULL)
333                 return;
334         while (atomic_read(&skb_shinfo(skb)->dataref) != 1 && i-- > 0)
335                 msleep(Sms);
336         if (i < 0) {
337                 printk(KERN_ERR
338                         "aoe: %s holds ref: %s\n",
339                         skb->dev ? skb->dev->name : "netif",
340                         "cannot free skb -- memory leaked.");
341                 return;
342         }
343         skb->truesize -= skb->data_len;
344         skb_shinfo(skb)->nr_frags = skb->data_len = 0;
345         skb_trim(skb, 0);
346         dev_kfree_skb(skb);
347 }
348
349 static void
350 skbpoolfree(struct aoedev *d)
351 {
352         struct sk_buff *skb, *tmp;
353
354         skb_queue_walk_safe(&d->skbpool, skb, tmp)
355                 skbfree(skb);
356
357         __skb_queue_head_init(&d->skbpool);
358 }
359
360 /* find it or allocate it */
361 struct aoedev *
362 aoedev_by_aoeaddr(ulong maj, int min, int do_alloc)
363 {
364         struct aoedev *d;
365         int i;
366         ulong flags;
367         ulong sysminor;
368
369         spin_lock_irqsave(&devlist_lock, flags);
370
371         for (d=devlist; d; d=d->next)
372                 if (d->aoemajor == maj && d->aoeminor == min) {
373                         d->ref++;
374                         break;
375                 }
376         if (d || !do_alloc || minor_get(&sysminor, maj, min) < 0)
377                 goto out;
378         d = kcalloc(1, sizeof *d, GFP_ATOMIC);
379         if (!d)
380                 goto out;
381         INIT_WORK(&d->work, aoecmd_sleepwork);
382         spin_lock_init(&d->lock);
383         skb_queue_head_init(&d->skbpool);
384         init_timer(&d->timer);
385         d->timer.data = (ulong) d;
386         d->timer.function = dummy_timer;
387         d->timer.expires = jiffies + HZ;
388         add_timer(&d->timer);
389         d->bufpool = NULL;      /* defer to aoeblk_gdalloc */
390         d->tgt = d->targets;
391         d->ref = 1;
392         for (i = 0; i < NFACTIVE; i++)
393                 INIT_LIST_HEAD(&d->factive[i]);
394         d->sysminor = sysminor;
395         d->aoemajor = maj;
396         d->aoeminor = min;
397         d->mintimer = MINTIMER;
398         d->next = devlist;
399         devlist = d;
400  out:
401         spin_unlock_irqrestore(&devlist_lock, flags);
402         return d;
403 }
404
405 static void
406 freetgt(struct aoedev *d, struct aoetgt *t)
407 {
408         struct frame *f;
409         struct list_head *pos, *nx, *head;
410         struct aoeif *ifp;
411
412         for (ifp = t->ifs; ifp < &t->ifs[NAOEIFS]; ++ifp) {
413                 if (!ifp->nd)
414                         break;
415                 dev_put(ifp->nd);
416         }
417
418         head = &t->ffree;
419         list_for_each_safe(pos, nx, head) {
420                 list_del(pos);
421                 f = list_entry(pos, struct frame, head);
422                 skbfree(f->skb);
423                 kfree(f);
424         }
425         kfree(t);
426 }
427
428 void
429 aoedev_exit(void)
430 {
431         struct aoedev *d;
432         ulong flags;
433
434         aoe_flush_iocq();
435         while ((d = devlist)) {
436                 devlist = d->next;
437
438                 spin_lock_irqsave(&d->lock, flags);
439                 aoedev_downdev(d);
440                 d->flags |= DEVFL_TKILL;
441                 spin_unlock_irqrestore(&d->lock, flags);
442
443                 del_timer_sync(&d->timer);
444                 aoedev_freedev(d);
445         }
446 }
447
448 int __init
449 aoedev_init(void)
450 {
451         return 0;
452 }