Skip to content

Commit

Permalink
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/mst/vhost

Pull vhost updates from Michael Tsirkin:
 "virtio, vhost: optimizations, fixes

  Looks like a quiet cycle for vhost/virtio, just a couple of minor
  tweaks. Most notable is automatic interrupt affinity for blk and scsi.
  Hopefully other devices are not far behind"

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
  virtio-console: avoid DMA from stack
  vhost: introduce O(1) vq metadata cache
  virtio_scsi: use virtio IRQ affinity
  virtio_blk: use virtio IRQ affinity
  blk-mq: provide a default queue mapping for virtio device
  virtio: provide a method to get the IRQ affinity mask for a virtqueue
  virtio: allow drivers to request IRQ affinity when creating VQs
  virtio_pci: simplify MSI-X setup
  virtio_pci: don't duplicate the msix_enable flag in struct pci_dev
  virtio_pci: use shared interrupts for virtqueues
  virtio_pci: remove struct virtio_pci_vq_info
  vhost: try avoiding avail index access when getting descriptor
  virtio_mmio: expose header to userspace
  • Loading branch information
torvalds committed Mar 2, 2017
2 parents 0f221a3 + c4baad5 commit 54d7989
Show file tree
Hide file tree
Showing 31 changed files with 456 additions and 454 deletions.
5 changes: 5 additions & 0 deletions block/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,9 @@ config BLK_MQ_PCI
depends on BLOCK && PCI
default y

config BLK_MQ_VIRTIO
bool
depends on BLOCK && VIRTIO
default y

source block/Kconfig.iosched
1 change: 1 addition & 0 deletions block/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o
obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o t10-pi.o
obj-$(CONFIG_BLK_MQ_PCI) += blk-mq-pci.o
obj-$(CONFIG_BLK_MQ_VIRTIO) += blk-mq-virtio.o
obj-$(CONFIG_BLK_DEV_ZONED) += blk-zoned.o
obj-$(CONFIG_BLK_WBT) += blk-wbt.o
obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-debugfs.o
Expand Down
54 changes: 54 additions & 0 deletions block/blk-mq-virtio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2016 Christoph Hellwig.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/device.h>
#include <linux/blk-mq.h>
#include <linux/blk-mq-virtio.h>
#include <linux/virtio_config.h>
#include <linux/module.h>
#include "blk-mq.h"

/**
* blk_mq_virtio_map_queues - provide a default queue mapping for virtio device
* @set: tagset to provide the mapping for
* @vdev: virtio device associated with @set.
* @first_vec: first interrupt vectors to use for queues (usually 0)
*
* This function assumes the virtio device @vdev has at least as many available
* interrupt vetors as @set has queues. It will then queuery the vector
* corresponding to each queue for it's affinity mask and built queue mapping
* that maps a queue to the CPUs that have irq affinity for the corresponding
* vector.
*/
int blk_mq_virtio_map_queues(struct blk_mq_tag_set *set,
struct virtio_device *vdev, int first_vec)
{
const struct cpumask *mask;
unsigned int queue, cpu;

if (!vdev->config->get_vq_affinity)
goto fallback;

for (queue = 0; queue < set->nr_hw_queues; queue++) {
mask = vdev->config->get_vq_affinity(vdev, first_vec + queue);
if (!mask)
goto fallback;

for_each_cpu(cpu, mask)
set->mq_map[cpu] = queue;
}

return 0;
fallback:
return blk_mq_map_queues(set);
}
EXPORT_SYMBOL_GPL(blk_mq_virtio_map_queues);
14 changes: 13 additions & 1 deletion drivers/block/virtio_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
#include <linux/hdreg.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>
#include <linux/virtio.h>
#include <linux/virtio_blk.h>
#include <linux/scatterlist.h>
#include <linux/string_helpers.h>
#include <scsi/scsi_cmnd.h>
#include <linux/idr.h>
#include <linux/blk-mq.h>
#include <linux/blk-mq-virtio.h>
#include <linux/numa.h>

#define PART_BITS 4
Expand Down Expand Up @@ -426,6 +428,7 @@ static int init_vq(struct virtio_blk *vblk)
struct virtqueue **vqs;
unsigned short num_vqs;
struct virtio_device *vdev = vblk->vdev;
struct irq_affinity desc = { 0, };

err = virtio_cread_feature(vdev, VIRTIO_BLK_F_MQ,
struct virtio_blk_config, num_queues,
Expand All @@ -452,7 +455,8 @@ static int init_vq(struct virtio_blk *vblk)
}

/* Discover virtqueues and write information to configuration. */
err = vdev->config->find_vqs(vdev, num_vqs, vqs, callbacks, names);
err = vdev->config->find_vqs(vdev, num_vqs, vqs, callbacks, names,
&desc);
if (err)
goto out;

Expand Down Expand Up @@ -586,10 +590,18 @@ static int virtblk_init_request(void *data, struct request *rq,
return 0;
}

static int virtblk_map_queues(struct blk_mq_tag_set *set)
{
struct virtio_blk *vblk = set->driver_data;

return blk_mq_virtio_map_queues(set, vblk->vdev, 0);
}

static struct blk_mq_ops virtio_mq_ops = {
.queue_rq = virtio_queue_rq,
.complete = virtblk_request_done,
.init_request = virtblk_init_request,
.map_queues = virtblk_map_queues,
};

static unsigned int virtblk_queue_depth;
Expand Down
14 changes: 11 additions & 3 deletions drivers/char/virtio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,8 @@ static int put_chars(u32 vtermno, const char *buf, int count)
{
struct port *port;
struct scatterlist sg[1];
void *data;
int ret;

if (unlikely(early_put_chars))
return early_put_chars(vtermno, buf, count);
Expand All @@ -1144,8 +1146,14 @@ static int put_chars(u32 vtermno, const char *buf, int count)
if (!port)
return -EPIPE;

sg_init_one(sg, buf, count);
return __send_to_port(port, sg, 1, count, (void *)buf, false);
data = kmemdup(buf, count, GFP_ATOMIC);
if (!data)
return -ENOMEM;

sg_init_one(sg, data, count);
ret = __send_to_port(port, sg, 1, count, data, false);
kfree(data);
return ret;
}

/*
Expand Down Expand Up @@ -1939,7 +1947,7 @@ static int init_vqs(struct ports_device *portdev)
/* Find the queues. */
err = portdev->vdev->config->find_vqs(portdev->vdev, nr_queues, vqs,
io_callbacks,
(const char **)io_names);
(const char **)io_names, NULL);
if (err)
goto free;

Expand Down
2 changes: 1 addition & 1 deletion drivers/crypto/virtio/virtio_crypto_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static int virtcrypto_find_vqs(struct virtio_crypto *vi)
}

ret = vi->vdev->config->find_vqs(vi->vdev, total_vqs, vqs, callbacks,
names);
names, NULL);
if (ret)
goto err_find;

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/virtio/virtgpu_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags)
#endif

ret = vgdev->vdev->config->find_vqs(vgdev->vdev, 2, vqs,
callbacks, names);
callbacks, names, NULL);
if (ret) {
DRM_ERROR("failed to find virt queues\n");
goto err_vqs;
Expand Down
2 changes: 1 addition & 1 deletion drivers/misc/mic/vop/vop_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
static int vop_find_vqs(struct virtio_device *dev, unsigned nvqs,
struct virtqueue *vqs[],
vq_callback_t *callbacks[],
const char * const names[])
const char * const names[], struct irq_affinity *desc)
{
struct _vop_vdev *vdev = to_vopvdev(dev);
struct vop_device *vpdev = vdev->vpdev;
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/caif/caif_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,8 @@ static int cfv_probe(struct virtio_device *vdev)
goto err;

/* Get the TX virtio ring. This is a "guest side vring". */
err = vdev->config->find_vqs(vdev, 1, &cfv->vq_tx, &vq_cbs, &names);
err = vdev->config->find_vqs(vdev, 1, &cfv->vq_tx, &vq_cbs, &names,
NULL);
if (err)
goto err;

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -2080,7 +2080,7 @@ static int virtnet_find_vqs(struct virtnet_info *vi)
}

ret = vi->vdev->config->find_vqs(vi->vdev, total_vqs, vqs, callbacks,
names);
names, NULL);
if (ret)
goto err_find;

Expand Down
3 changes: 2 additions & 1 deletion drivers/remoteproc/remoteproc_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ static void rproc_virtio_del_vqs(struct virtio_device *vdev)
static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
struct virtqueue *vqs[],
vq_callback_t *callbacks[],
const char * const names[])
const char * const names[],
struct irq_affinity *desc)
{
int i, ret;

Expand Down
2 changes: 1 addition & 1 deletion drivers/rpmsg/virtio_rpmsg_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ static int rpmsg_probe(struct virtio_device *vdev)
init_waitqueue_head(&vrp->sendq);

/* We expect two virtqueues, rx and tx (and in this order) */
err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, names);
err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, names, NULL);
if (err)
goto free_vrp;

Expand Down
3 changes: 2 additions & 1 deletion drivers/s390/virtio/kvm_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,8 @@ static void kvm_del_vqs(struct virtio_device *vdev)
static int kvm_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[],
vq_callback_t *callbacks[],
const char * const names[])
const char * const names[],
struct irq_affinity *desc)
{
struct kvm_device *kdev = to_kvmdev(vdev);
int i;
Expand Down
3 changes: 2 additions & 1 deletion drivers/s390/virtio/virtio_ccw.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,8 @@ static int virtio_ccw_register_adapter_ind(struct virtio_ccw_device *vcdev,
static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[],
vq_callback_t *callbacks[],
const char * const names[])
const char * const names[],
struct irq_affinity *desc)
{
struct virtio_ccw_device *vcdev = to_vc_device(vdev);
unsigned long *indicatorp = NULL;
Expand Down
Loading

0 comments on commit 54d7989

Please sign in to comment.