1 #include <linux/module.h>
2 #include <linux/device.h>
3 #include <linux/signal.h>
4 #include <linux/sched.h>
5 #include <linux/poll.h>
6 #include <linux/blkdev.h>
10 int blktap_ring_major;
13 * BLKTAP - immediately before the mmap area,
14 * we have a bunch of pages reserved for shared memory rings.
19 blktap_ring_read_response(struct blktap *tap,
20 const struct blkif_response *rsp)
22 struct blktap_ring *ring = &tap->ring;
23 struct blktap_request *request;
29 if (usr_idx < 0 || usr_idx >= MAX_PENDING_REQS) {
34 request = ring->pending[usr_idx];
41 if (rsp->operation != request->operation) {
47 "request %d [%p] response: %d\n",
48 request->usr_idx, request, rsp->status);
50 err = rsp->status == BLKIF_RSP_OKAY ? 0 : -EIO;
52 blktap_device_end_request(tap, request, err);
57 "invalid response, idx:%d status:%d op:%d/%d: err %d\n",
59 rsp->operation, request->operation,
66 blktap_read_ring(struct blktap *tap)
68 struct blktap_ring *ring = &tap->ring;
69 struct blkif_response rsp;
72 down_read(¤t->mm->mmap_sem);
74 up_read(¤t->mm->mmap_sem);
78 /* for each outstanding message on the ring */
79 rp = ring->ring.sring->rsp_prod;
82 for (rc = ring->ring.rsp_cons; rc != rp; rc++) {
83 memcpy(&rsp, RING_GET_RESPONSE(&ring->ring, rc), sizeof(rsp));
84 blktap_ring_read_response(tap, &rsp);
87 ring->ring.rsp_cons = rc;
89 up_read(¤t->mm->mmap_sem);
92 static int blktap_ring_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
94 return VM_FAULT_SIGBUS;
98 blktap_ring_fail_pending(struct blktap *tap)
100 struct blktap_ring *ring = &tap->ring;
101 struct blktap_request *request;
104 for (usr_idx = 0; usr_idx < MAX_PENDING_REQS; usr_idx++) {
105 request = ring->pending[usr_idx];
109 blktap_device_end_request(tap, request, -EIO);
114 blktap_ring_vm_close(struct vm_area_struct *vma)
116 struct blktap *tap = vma->vm_private_data;
117 struct blktap_ring *ring = &tap->ring;
118 struct page *page = virt_to_page(ring->ring.sring);
120 blktap_ring_fail_pending(tap);
122 zap_page_range(vma, vma->vm_start, PAGE_SIZE, NULL);
123 ClearPageReserved(page);
128 if (test_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse))
129 blktap_control_destroy_tap(tap);
132 static struct vm_operations_struct blktap_ring_vm_operations = {
133 .close = blktap_ring_vm_close,
134 .fault = blktap_ring_fault,
138 blktap_ring_map_segment(struct blktap *tap,
139 struct blktap_request *request,
142 struct blktap_ring *ring = &tap->ring;
145 uaddr = MMAP_VADDR(ring->user_vstart, request->usr_idx, seg);
146 return vm_insert_page(ring->vma, uaddr, request->pages[seg]);
150 blktap_ring_map_request(struct blktap *tap,
151 struct blktap_request *request)
156 write = request->operation != BLKIF_OP_READ;
158 for (seg = 0; seg < request->nr_pages; seg++) {
160 blktap_request_bounce(tap, request, seg, 1);
162 err = blktap_ring_map_segment(tap, request, seg);
168 blktap_ring_unmap_request(tap, request);
174 blktap_ring_unmap_request(struct blktap *tap,
175 struct blktap_request *request)
177 struct blktap_ring *ring = &tap->ring;
182 uaddr = MMAP_VADDR(ring->user_vstart, request->usr_idx, 0);
183 size = request->nr_pages << PAGE_SHIFT;
184 read = request->operation != BLKIF_OP_WRITE;
187 for (seg = 0; seg < request->nr_pages; seg++)
188 blktap_request_bounce(tap, request, seg, 0);
190 zap_page_range(ring->vma, uaddr, size, NULL);
194 blktap_ring_free_request(struct blktap *tap,
195 struct blktap_request *request)
197 struct blktap_ring *ring = &tap->ring;
199 ring->pending[request->usr_idx] = NULL;
202 blktap_request_free(tap, request);
205 struct blktap_request*
206 blktap_ring_make_request(struct blktap *tap)
208 struct blktap_ring *ring = &tap->ring;
209 struct blktap_request *request;
212 if (RING_FULL(&ring->ring))
213 return ERR_PTR(-ENOSPC);
215 request = blktap_request_alloc(tap);
217 return ERR_PTR(-ENOMEM);
219 for (usr_idx = 0; usr_idx < BLK_RING_SIZE; usr_idx++)
220 if (!ring->pending[usr_idx])
223 BUG_ON(usr_idx >= BLK_RING_SIZE);
226 request->usr_idx = usr_idx;
228 ring->pending[usr_idx] = request;
235 blktap_ring_submit_request(struct blktap *tap,
236 struct blktap_request *request)
238 struct blktap_ring *ring = &tap->ring;
239 struct blkif_request *breq;
240 struct scatterlist *sg;
244 "request %d [%p] submit\n", request->usr_idx, request);
246 breq = RING_GET_REQUEST(&ring->ring, ring->ring.req_prod_pvt);
248 breq->id = request->usr_idx;
249 breq->sector_number = blk_rq_pos(request->rq);
251 breq->operation = request->operation;
252 breq->nr_segments = request->nr_pages;
254 blktap_for_each_sg(sg, request, i) {
255 struct blkif_request_segment *seg = &breq->seg[i];
258 count = sg->length >> 9;
259 first = sg->offset >> 9;
261 seg->first_sect = first;
262 seg->last_sect = first + count - 1;
267 ring->ring.req_prod_pvt++;
269 do_gettimeofday(&request->time);
272 switch (request->operation) {
274 tap->stats.st_wr_sect += nsecs;
275 tap->stats.st_wr_req++;
279 tap->stats.st_rd_sect += nsecs;
280 tap->stats.st_rd_req++;
283 case BLKIF_OP_PACKET:
284 tap->stats.st_pk_req++;
290 blktap_ring_open(struct inode *inode, struct file *filp)
292 struct blktap *tap = NULL;
295 minor = iminor(inode);
297 if (minor < blktap_max_minor)
298 tap = blktaps[minor];
303 if (test_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse))
309 filp->private_data = tap;
310 tap->ring.task = current;
316 blktap_ring_release(struct inode *inode, struct file *filp)
318 struct blktap *tap = filp->private_data;
320 blktap_device_destroy_sync(tap);
322 tap->ring.task = NULL;
324 if (test_bit(BLKTAP_SHUTDOWN_REQUESTED, &tap->dev_inuse))
325 blktap_control_destroy_tap(tap);
331 blktap_ring_mmap(struct file *filp, struct vm_area_struct *vma)
333 struct blktap *tap = filp->private_data;
334 struct blktap_ring *ring = &tap->ring;
335 struct blkif_sring *sring;
336 struct page *page = NULL;
342 page = alloc_page(GFP_KERNEL|__GFP_ZERO);
346 SetPageReserved(page);
348 err = vm_insert_page(vma, vma->vm_start, page);
352 sring = page_address(page);
353 SHARED_RING_INIT(sring);
354 FRONT_RING_INIT(&ring->ring, sring, PAGE_SIZE);
356 ring->ring_vstart = vma->vm_start;
357 ring->user_vstart = ring->ring_vstart + PAGE_SIZE;
359 vma->vm_private_data = tap;
361 vma->vm_flags |= VM_DONTCOPY;
362 vma->vm_flags |= VM_RESERVED;
364 vma->vm_ops = &blktap_ring_vm_operations;
371 zap_page_range(vma, vma->vm_start, PAGE_SIZE, NULL);
372 ClearPageReserved(page);
380 blktap_ring_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
382 struct blktap *tap = filp->private_data;
383 struct blktap_ring *ring = &tap->ring;
385 BTDBG("%d: cmd: %u, arg: %lu\n", tap->minor, cmd, arg);
387 if (!ring->vma || ring->vma->vm_mm != current->mm)
391 case BLKTAP2_IOCTL_KICK_FE:
393 blktap_read_ring(tap);
396 case BLKTAP2_IOCTL_CREATE_DEVICE: {
397 struct blktap_params params;
398 void __user *ptr = (void *)arg;
403 if (copy_from_user(¶ms, ptr, sizeof(params)))
406 return blktap_device_create(tap, ¶ms);
409 case BLKTAP2_IOCTL_REMOVE_DEVICE:
411 return blktap_device_destroy(tap);
417 static unsigned int blktap_ring_poll(struct file *filp, poll_table *wait)
419 struct blktap *tap = filp->private_data;
420 struct blktap_ring *ring = &tap->ring;
423 poll_wait(filp, &tap->pool->wait, wait);
424 poll_wait(filp, &ring->poll_wait, wait);
426 down_read(¤t->mm->mmap_sem);
427 if (ring->vma && tap->device.gd)
428 blktap_device_run_queue(tap);
429 up_read(¤t->mm->mmap_sem);
431 work = ring->ring.req_prod_pvt - ring->ring.sring->req_prod;
432 RING_PUSH_REQUESTS(&ring->ring);
435 ring->ring.sring->private.tapif_user.msg ||
436 test_and_clear_bit(BLKTAP_DEVICE_CLOSED, &tap->dev_inuse))
437 return POLLIN | POLLRDNORM;
442 static const struct file_operations blktap_ring_file_operations = {
443 .owner = THIS_MODULE,
444 .open = blktap_ring_open,
445 .release = blktap_ring_release,
446 .unlocked_ioctl = blktap_ring_ioctl,
447 .mmap = blktap_ring_mmap,
448 .poll = blktap_ring_poll,
452 blktap_ring_kick_user(struct blktap *tap)
454 wake_up(&tap->ring.poll_wait);
458 blktap_ring_destroy(struct blktap *tap)
460 struct blktap_ring *ring = &tap->ring;
462 if (ring->task || ring->vma)
469 blktap_ring_create(struct blktap *tap)
471 struct blktap_ring *ring = &tap->ring;
473 init_waitqueue_head(&ring->poll_wait);
474 ring->devno = MKDEV(blktap_ring_major, tap->minor);
480 blktap_ring_debug(struct blktap *tap, char *buf, size_t size)
482 struct blktap_ring *ring = &tap->ring;
483 char *s = buf, *end = buf + size;
486 s += snprintf(s, end - s,
487 "begin pending:%d\n", ring->n_pending);
489 for (usr_idx = 0; usr_idx < MAX_PENDING_REQS; usr_idx++) {
490 struct blktap_request *request;
491 struct timeval *time;
494 request = ring->pending[usr_idx];
498 switch (request->operation) {
499 case BLKIF_OP_WRITE: op = 'W'; break;
500 case BLKIF_OP_READ: op = 'R'; break;
501 case BLKIF_OP_PACKET: op = 'P'; break;
503 time = &request->time;
505 s += snprintf(s, end - s,
506 "%02d: usr_idx:%02d "
507 "op:%c nr_pages:%02d time:%lu.%09lu\n",
508 usr_idx, request->usr_idx,
509 op, request->nr_pages,
510 time->tv_sec, time->tv_usec);
513 s += snprintf(s, end - s, "end pending\n");
520 blktap_ring_init(void)
524 err = __register_chrdev(0, 0, CONFIG_XEN_NR_TAP2_DEVICES, "blktap2",
525 &blktap_ring_file_operations);
527 BTERR("error registering ring devices: %d\n", err);
531 blktap_ring_major = err;
532 BTINFO("blktap ring major: %d\n", blktap_ring_major);
538 blktap_ring_exit(void)
540 if (!blktap_ring_major)
543 __unregister_chrdev(blktap_ring_major, 0, CONFIG_XEN_NR_TAP2_DEVICES,
546 blktap_ring_major = 0;