aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 11:37:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 11:37:05 -0500
commitb7dfde956daee23f4439d0c8562a5e38b43e79d9 (patch)
tree2ed71fb5c5eac6957fd1e1ad0a67be6c3282167a
parent03c850ec327c42a97e44c448b75983e12da417d9 (diff)
parent1b6370463e88b0c1c317de16d7b962acc1dab4f2 (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.c329
-rw-r--r--drivers/lguest/core.c2
-rw-r--r--drivers/net/virtio_net.c48
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c6
-rw-r--r--drivers/scsi/virtio_scsi.c24
-rw-r--r--drivers/virtio/virtio.c30
-rw-r--r--drivers/virtio/virtio_balloon.c7
-rw-r--r--drivers/virtio/virtio_mmio.c30
-rw-r--r--drivers/virtio/virtio_pci.c20
-rw-r--r--drivers/virtio/virtio_ring.c46
-rw-r--r--include/linux/virtio.h25
-rw-r--r--include/linux/virtio_scsi.h28
-rw-r--r--include/uapi/linux/virtio_ids.h1
-rw-r--r--mm/highmem.c1
-rw-r--r--net/9p/trans_virtio.c3
-rw-r--r--tools/lguest/lguest.c84
-rw-r--r--tools/virtio/virtio_test.c4
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
347static bool is_rproc_serial(const struct virtio_device *vdev)
348{
349 return is_rproc_enabled && vdev->id.device == VIRTIO_ID_RPROC_SERIAL;
350}
351
328static inline bool use_multiport(struct ports_device *portdev) 352static 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
339static void free_buf(struct port_buffer *buf) 363static DEFINE_SPINLOCK(dma_bufs_lock);
364static LIST_HEAD(pending_free_dma_bufs);
365
366static 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
345static struct port_buffer *alloc_buf(size_t buf_size) 399static 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
421static 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)