diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-20 11:37:04 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-20 11:37:05 -0500 |
| commit | b7dfde956daee23f4439d0c8562a5e38b43e79d9 (patch) | |
| tree | 2ed71fb5c5eac6957fd1e1ad0a67be6c3282167a | |
| parent | 03c850ec327c42a97e44c448b75983e12da417d9 (diff) | |
| parent | 1b6370463e88b0c1c317de16d7b962acc1dab4f2 (diff) | |
Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull virtio update from Rusty Russell:
"Some nice cleanups, and even a patch my wife did as a "live" demo for
Latinoware 2012.
There's a slightly non-trivial merge in virtio-net, as we cleaned up
the virtio add_buf interface while DaveM accepted the mq virtio-net
patches."
* tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: (27 commits)
virtio_console: Add support for remoteproc serial
virtio_console: Merge struct buffer_token into struct port_buffer
virtio: add drv_to_virtio to make code clearly
virtio: use dev_to_virtio wrapper in virtio
virtio-mmio: Fix irq parsing in command line parameter
virtio_console: Free buffers from out-queue upon close
virtio: Convert dev_printk(KERN_<LEVEL> to dev_<level>(
virtio_console: Use kmalloc instead of kzalloc
virtio_console: Free buffer if splice fails
virtio: tools: make it clear that virtqueue_add_buf() no longer returns > 0
virtio: scsi: make it clear that virtqueue_add_buf() no longer returns > 0
virtio: rpmsg: make it clear that virtqueue_add_buf() no longer returns > 0
virtio: net: make it clear that virtqueue_add_buf() no longer returns > 0
virtio: console: make it clear that virtqueue_add_buf() no longer returns > 0
virtio: make virtqueue_add_buf() returning 0 on success, not capacity.
virtio: console: don't rely on virtqueue_add_buf() returning capacity.
virtio_net: don't rely on virtqueue_add_buf() returning capacity.
virtio-net: remove unused skb_vnet_hdr->num_sg field
virtio-net: correct capacity math on ring full
virtio: move queue_index and num_free fields into core struct virtqueue.
...
| -rw-r--r-- | drivers/char/virtio_console.c | 329 | ||||
| -rw-r--r-- | drivers/lguest/core.c | 2 | ||||
| -rw-r--r-- | drivers/net/virtio_net.c | 48 | ||||
| -rw-r--r-- | drivers/rpmsg/virtio_rpmsg_bus.c | 6 | ||||
| -rw-r--r-- | drivers/scsi/virtio_scsi.c | 24 | ||||
| -rw-r--r-- | drivers/virtio/virtio.c | 30 | ||||
| -rw-r--r-- | drivers/virtio/virtio_balloon.c | 7 | ||||
| -rw-r--r-- | drivers/virtio/virtio_mmio.c | 30 | ||||
| -rw-r--r-- | drivers/virtio/virtio_pci.c | 20 | ||||
| -rw-r--r-- | drivers/virtio/virtio_ring.c | 46 | ||||
| -rw-r--r-- | include/linux/virtio.h | 25 | ||||
| -rw-r--r-- | include/linux/virtio_scsi.h | 28 | ||||
| -rw-r--r-- | include/uapi/linux/virtio_ids.h | 1 | ||||
| -rw-r--r-- | mm/highmem.c | 1 | ||||
| -rw-r--r-- | net/9p/trans_virtio.c | 3 | ||||
| -rw-r--r-- | tools/lguest/lguest.c | 84 | ||||
| -rw-r--r-- | tools/virtio/virtio_test.c | 4 |
17 files changed, 412 insertions, 276 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 90493d4ead1f..c594cb16c37b 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
| @@ -37,8 +37,12 @@ | |||
| 37 | #include <linux/wait.h> | 37 | #include <linux/wait.h> |
| 38 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
| 39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
| 40 | #include <linux/dma-mapping.h> | ||
| 41 | #include <linux/kconfig.h> | ||
| 40 | #include "../tty/hvc/hvc_console.h" | 42 | #include "../tty/hvc/hvc_console.h" |
| 41 | 43 | ||
| 44 | #define is_rproc_enabled IS_ENABLED(CONFIG_REMOTEPROC) | ||
| 45 | |||
| 42 | /* | 46 | /* |
| 43 | * This is a global struct for storing common data for all the devices | 47 | * This is a global struct for storing common data for all the devices |
| 44 | * this driver handles. | 48 | * this driver handles. |
| @@ -111,6 +115,21 @@ struct port_buffer { | |||
| 111 | size_t len; | 115 | size_t len; |
| 112 | /* offset in the buf from which to consume data */ | 116 | /* offset in the buf from which to consume data */ |
| 113 | size_t offset; | 117 | size_t offset; |
| 118 | |||
| 119 | /* DMA address of buffer */ | ||
| 120 | dma_addr_t dma; | ||
| 121 | |||
| 122 | /* Device we got DMA memory from */ | ||
| 123 | struct device *dev; | ||
| 124 | |||
| 125 | /* List of pending dma buffers to free */ | ||
| 126 | struct list_head list; | ||
| 127 | |||
| 128 | /* If sgpages == 0 then buf is used */ | ||
| 129 | unsigned int sgpages; | ||
| 130 | |||
| 131 | /* sg is used if spages > 0. sg must be the last in is struct */ | ||
| 132 | struct scatterlist sg[0]; | ||
| 114 | }; | 133 | }; |
| 115 | 134 | ||
| 116 | /* | 135 | /* |
| @@ -325,6 +344,11 @@ static bool is_console_port(struct port *port) | |||
| 325 | return false; | 344 | return false; |
| 326 | } | 345 | } |
| 327 | 346 | ||
| 347 | static bool is_rproc_serial(const struct virtio_device *vdev) | ||
| 348 | { | ||
| 349 | return is_rproc_enabled && vdev->id.device == VIRTIO_ID_RPROC_SERIAL; | ||
| 350 | } | ||
| 351 | |||
| 328 | static inline bool use_multiport(struct ports_device *portdev) | 352 | static inline bool use_multiport(struct ports_device *portdev) |
| 329 | { | 353 | { |
| 330 | /* | 354 | /* |
| @@ -336,20 +360,110 @@ static inline bool use_multiport(struct ports_device *portdev) | |||
| 336 | return portdev->vdev->features[0] & (1 << VIRTIO_CONSOLE_F_MULTIPORT); | 360 | return portdev->vdev->features[0] & (1 << VIRTIO_CONSOLE_F_MULTIPORT); |
| 337 | } | 361 | } |
| 338 | 362 | ||
| 339 | static void free_buf(struct port_buffer *buf) | 363 | static DEFINE_SPINLOCK(dma_bufs_lock); |
| 364 | static LIST_HEAD(pending_free_dma_bufs); | ||
| 365 | |||
| 366 | static void free_buf(struct port_buffer *buf, bool can_sleep) | ||
| 340 | { | 367 | { |
| 341 | kfree(buf->buf); | 368 | unsigned int i; |
| 369 | |||
| 370 | for (i = 0; i < buf->sgpages; i++) { | ||
| 371 | struct page *page = sg_page(&buf->sg[i]); | ||
| 372 | if (!page) | ||
| 373 | break; | ||
| 374 | put_page(page); | ||
| 375 | } | ||
| 376 | |||
| 377 | if (!buf->dev) { | ||
| 378 | kfree(buf->buf); | ||
| 379 | } else if (is_rproc_enabled) { | ||
| 380 | unsigned long flags; | ||
| 381 | |||
| 382 | /* dma_free_coherent requires interrupts to be enabled. */ | ||
| 383 | if (!can_sleep) { | ||
| 384 | /* queue up dma-buffers to be freed later */ | ||
| 385 | spin_lock_irqsave(&dma_bufs_lock, flags); | ||
| 386 | list_add_tail(&buf->list, &pending_free_dma_bufs); | ||
| 387 | spin_unlock_irqrestore(&dma_bufs_lock, flags); | ||
| 388 | return; | ||
| 389 | } | ||
| 390 | dma_free_coherent(buf->dev, buf->size, buf->buf, buf->dma); | ||
| 391 | |||
| 392 | /* Release device refcnt and allow it to be freed */ | ||
| 393 | put_device(buf->dev); | ||
| 394 | } | ||
| 395 | |||
| 342 | kfree(buf); | 396 | kfree(buf); |
| 343 | } | 397 | } |
| 344 | 398 | ||
| 345 | static struct port_buffer *alloc_buf(size_t buf_size) | 399 | static void reclaim_dma_bufs(void) |
| 400 | { | ||
| 401 | unsigned long flags; | ||
| 402 | struct port_buffer *buf, *tmp; | ||
| 403 | LIST_HEAD(tmp_list); | ||
| 404 | |||
| 405 | if (list_empty(&pending_free_dma_bufs)) | ||
| 406 | return; | ||
| 407 | |||
| 408 | /* Create a copy of the pending_free_dma_bufs while holding the lock */ | ||
| 409 | spin_lock_irqsave(&dma_bufs_lock, flags); | ||
| 410 | list_cut_position(&tmp_list, &pending_free_dma_bufs, | ||
| 411 | pending_free_dma_bufs.prev); | ||
| 412 | spin_unlock_irqrestore(&dma_bufs_lock, flags); | ||
| 413 | |||
| 414 | /* Release the dma buffers, without irqs enabled */ | ||
| 415 | list_for_each_entry_safe(buf, tmp, &tmp_list, list) { | ||
| 416 | list_del(&buf->list); | ||
| 417 | free_buf(buf, true); | ||
| 418 | } | ||
| 419 | } | ||
| 420 | |||
| 421 | static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size, | ||
| 422 | int pages) | ||
| 346 | { | 423 | { |
| 347 | struct port_buffer *buf; | 424 | struct port_buffer *buf; |
| 348 | 425 | ||
| 349 | buf = kmalloc(sizeof(*buf), GFP_KERNEL); | 426 | reclaim_dma_bufs(); |
| 427 | |||
| 428 | /* | ||
| 429 | * Allocate buffer and the sg list. The sg list array is allocated | ||
| 430 | * directly after the port_buffer struct. | ||
| 431 | */ | ||
| 432 | buf = kmalloc(sizeof(*buf) + sizeof(struct scatterlist) * pages, | ||
| 433 | GFP_KERNEL); | ||
| 350 | if (!buf) | 434 | if (!buf) |
| 351 | goto fail; | 435 | goto fail; |
| 352 | buf->buf = kzalloc(buf_size, GFP_KERNEL); | 436 | |
| 437 | buf->sgpages = pages; | ||
| 438 | if (pages > 0) { | ||
| 439 | buf->dev = NULL; | ||
| 440 | buf->buf = NULL; | ||
| 441 | return buf; | ||
| 442 | } | ||
| 443 | |||
| 444 | if (is_rproc_serial(vq->vdev)) { | ||
| 445 | /* | ||
| 446 | * Allocate DMA memory from ancestor. When a virtio | ||
| 447 | * device is created by remoteproc, the DMA memory is | ||
| 448 | * associated with the grandparent device: | ||
| 449 | * vdev => rproc => platform-dev. | ||
| 450 | * The code here would have been less quirky if | ||
| 451 | * DMA_MEMORY_INCLUDES_CHILDREN had been supported | ||
| 452 | * in dma-coherent.c | ||
| 453 | */ | ||
| 454 | if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent) | ||
