3968fe6c007730e3b83fe55acab75085febaee8e
[deliverable/linux.git] / drivers / block / aoe / aoedev.c
1 /* Copyright (c) 2007 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 "aoe.h"
13
14 static void dummy_timer(ulong);
15 static void aoedev_freedev(struct aoedev *);
16 static void freetgt(struct aoedev *d, struct aoetgt *t);
17 static void skbpoolfree(struct aoedev *d);
18
19 static struct aoedev *devlist;
20 static DEFINE_SPINLOCK(devlist_lock);
21
22 /*
23 * Users who grab a pointer to the device with aoedev_by_aoeaddr or
24 * aoedev_by_sysminor_m automatically get a reference count and must
25 * be responsible for performing a aoedev_put. With the addition of
26 * async kthread processing I'm no longer confident that we can
27 * guarantee consistency in the face of device flushes.
28 *
29 * For the time being, we only bother to add extra references for
30 * frames sitting on the iocq. When the kthreads finish processing
31 * these frames, they will aoedev_put the device.
32 */
33 struct aoedev *
34 aoedev_by_aoeaddr(int maj, int min)
35 {
36 struct aoedev *d;
37 ulong flags;
38
39 spin_lock_irqsave(&devlist_lock, flags);
40
41 for (d=devlist; d; d=d->next)
42 if (d->aoemajor == maj && d->aoeminor == min) {
43 d->ref++;
44 break;
45 }
46
47 spin_unlock_irqrestore(&devlist_lock, flags);
48 return d;
49 }
50
51 void
52 aoedev_put(struct aoedev *d)
53 {
54 ulong flags;
55
56 spin_lock_irqsave(&devlist_lock, flags);
57 d->ref--;
58 spin_unlock_irqrestore(&devlist_lock, flags);
59 }
60
61 static void
62 dummy_timer(ulong vp)
63 {
64 struct aoedev *d;
65
66 d = (struct aoedev *)vp;
67 if (d->flags & DEVFL_TKILL)
68 return;
69 d->timer.expires = jiffies + HZ;
70 add_timer(&d->timer);
71 }
72
73 static void
74 aoe_failip(struct aoedev *d)
75 {
76 struct request *rq;
77 struct bio *bio;
78 unsigned long n;
79
80 aoe_failbuf(d, d->ip.buf);
81
82 rq = d->ip.rq;
83 if (rq == NULL)
84 return;
85 while ((bio = d->ip.nxbio)) {
86 clear_bit(BIO_UPTODATE, &bio->bi_flags);
87 d->ip.nxbio = bio->bi_next;
88 n = (unsigned long) rq->special;
89 rq->special = (void *) --n;
90 }
91 if ((unsigned long) rq->special == 0)
92 aoe_end_request(d, rq, 0);
93 }
94
95 void
96 aoedev_downdev(struct aoedev *d)
97 {
98 struct aoetgt *t, **tt, **te;
99 struct frame *f;
100 struct list_head *head, *pos, *nx;
101 struct request *rq;
102 int i;
103
104 d->flags &= ~DEVFL_UP;
105
106 /* clean out active buffers */
107 for (i = 0; i < NFACTIVE; i++) {
108 head = &d->factive[i];
109 list_for_each_safe(pos, nx, head) {
110 f = list_entry(pos, struct frame, head);
111 list_del(pos);
112 if (f->buf) {
113 f->buf->nframesout--;
114 aoe_failbuf(d, f->buf);
115 }
116 aoe_freetframe(f);
117 }
118 }
119 /* reset window dressings */
120 tt = d->targets;
121 te = tt + NTARGETS;
122 for (; tt < te && (t = *tt); tt++) {
123 t->maxout = t->nframes;
124 t->nout = 0;
125 }
126
127 /* clean out the in-process request (if any) */
128 aoe_failip(d);
129 d->htgt = NULL;
130
131 /* fast fail all pending I/O */
132 if (d->blkq) {
133 while ((rq = blk_peek_request(d->blkq))) {
134 blk_start_request(rq);
135 aoe_end_request(d, rq, 1);
136 }
137 }
138
139 if (d->gd)
140 set_capacity(d->gd, 0);
141 }
142
143 static void
144 aoedev_freedev(struct aoedev *d)
145 {
146 struct aoetgt **t, **e;
147
148 cancel_work_sync(&d->work);
149 if (d->gd) {
150 aoedisk_rm_sysfs(d);
151 del_gendisk(d->gd);
152 put_disk(d->gd);
153 blk_cleanup_queue(d->blkq);
154 }
155 t = d->targets;
156 e = t + NTARGETS;
157 for (; t < e && *t; t++)
158 freetgt(d, *t);
159 if (d->bufpool)
160 mempool_destroy(d->bufpool);
161 skbpoolfree(d);
162 kfree(d);
163 }
164
165 int
166 aoedev_flush(const char __user *str, size_t cnt)
167 {
168 ulong flags;
169 struct aoedev *d, **dd;
170 struct aoedev *rmd = NULL;
171 char buf[16];
172 int all = 0;
173
174 if (cnt >= 3) {
175 if (cnt > sizeof buf)
176 cnt = sizeof buf;
177 if (copy_from_user(buf, str, cnt))
178 return -EFAULT;
179 all = !strncmp(buf, "all", 3);
180 }
181
182 spin_lock_irqsave(&devlist_lock, flags);
183 dd = &devlist;
184 while ((d = *dd)) {
185 spin_lock(&d->lock);
186 if ((!all && (d->flags & DEVFL_UP))
187 || (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
188 || d->nopen
189 || d->ref) {
190 spin_unlock(&d->lock);
191 dd = &d->next;
192 continue;
193 }
194 *dd = d->next;
195 aoedev_downdev(d);
196 d->flags |= DEVFL_TKILL;
197 spin_unlock(&d->lock);
198 d->next = rmd;
199 rmd = d;
200 }
201 spin_unlock_irqrestore(&devlist_lock, flags);
202 while ((d = rmd)) {
203 rmd = d->next;
204 del_timer_sync(&d->timer);
205 aoedev_freedev(d); /* must be able to sleep */
206 }
207 return 0;
208 }
209
210 /* This has been confirmed to occur once with Tms=3*1000 due to the
211 * driver changing link and not processing its transmit ring. The
212 * problem is hard enough to solve by returning an error that I'm
213 * still punting on "solving" this.
214 */
215 static void
216 skbfree(struct sk_buff *skb)
217 {
218 enum { Sms = 250, Tms = 30 * 1000};
219 int i = Tms / Sms;
220
221 if (skb == NULL)
222 return;
223 while (atomic_read(&skb_shinfo(skb)->dataref) != 1 && i-- > 0)
224 msleep(Sms);
225 if (i < 0) {
226 printk(KERN_ERR
227 "aoe: %s holds ref: %s\n",
228 skb->dev ? skb->dev->name : "netif",
229 "cannot free skb -- memory leaked.");
230 return;
231 }
232 skb->truesize -= skb->data_len;
233 skb_shinfo(skb)->nr_frags = skb->data_len = 0;
234 skb_trim(skb, 0);
235 dev_kfree_skb(skb);
236 }
237
238 static void
239 skbpoolfree(struct aoedev *d)
240 {
241 struct sk_buff *skb, *tmp;
242
243 skb_queue_walk_safe(&d->skbpool, skb, tmp)
244 skbfree(skb);
245
246 __skb_queue_head_init(&d->skbpool);
247 }
248
249 /* find it or malloc it */
250 struct aoedev *
251 aoedev_by_sysminor_m(ulong sysminor)
252 {
253 struct aoedev *d;
254 int i;
255 ulong flags;
256
257 spin_lock_irqsave(&devlist_lock, flags);
258
259 for (d=devlist; d; d=d->next)
260 if (d->sysminor == sysminor) {
261 d->ref++;
262 break;
263 }
264 if (d)
265 goto out;
266 d = kcalloc(1, sizeof *d, GFP_ATOMIC);
267 if (!d)
268 goto out;
269 INIT_WORK(&d->work, aoecmd_sleepwork);
270 spin_lock_init(&d->lock);
271 skb_queue_head_init(&d->skbpool);
272 init_timer(&d->timer);
273 d->timer.data = (ulong) d;
274 d->timer.function = dummy_timer;
275 d->timer.expires = jiffies + HZ;
276 add_timer(&d->timer);
277 d->bufpool = NULL; /* defer to aoeblk_gdalloc */
278 d->tgt = d->targets;
279 d->ref = 1;
280 for (i = 0; i < NFACTIVE; i++)
281 INIT_LIST_HEAD(&d->factive[i]);
282 d->sysminor = sysminor;
283 d->aoemajor = AOEMAJOR(sysminor);
284 d->aoeminor = AOEMINOR(sysminor);
285 d->mintimer = MINTIMER;
286 d->next = devlist;
287 devlist = d;
288 out:
289 spin_unlock_irqrestore(&devlist_lock, flags);
290 return d;
291 }
292
293 static void
294 freetgt(struct aoedev *d, struct aoetgt *t)
295 {
296 struct frame *f;
297 struct list_head *pos, *nx, *head;
298
299 head = &t->ffree;
300 list_for_each_safe(pos, nx, head) {
301 list_del(pos);
302 f = list_entry(pos, struct frame, head);
303 skbfree(f->skb);
304 kfree(f);
305 }
306 kfree(t);
307 }
308
309 void
310 aoedev_exit(void)
311 {
312 struct aoedev *d;
313 ulong flags;
314
315 aoe_flush_iocq();
316 while ((d = devlist)) {
317 devlist = d->next;
318
319 spin_lock_irqsave(&d->lock, flags);
320 aoedev_downdev(d);
321 d->flags |= DEVFL_TKILL;
322 spin_unlock_irqrestore(&d->lock, flags);
323
324 del_timer_sync(&d->timer);
325 aoedev_freedev(d);
326 }
327 }
328
329 int __init
330 aoedev_init(void)
331 {
332 return 0;
333 }
This page took 0.03815 seconds and 4 git commands to generate.