From 4d32029b8ddb7be4d1699c6d8e1675ff5476d149 Mon Sep 17 00:00:00 2001 From: Tomáš Golembiovský Date: Sun, 12 Nov 2017 13:05:38 +0100 Subject: virtio_balloon: include disk/file caches memory statistics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new field VIRTIO_BALLOON_S_CACHES to virtio_balloon memory statistics protocol. The value represents all disk/file caches. In this case it corresponds to the sum of values Buffers+Cached+SwapCached from /proc/meminfo. Signed-off-by: Tomáš Golembiovský Signed-off-by: Michael S. Tsirkin --- drivers/virtio/virtio_balloon.c | 4 ++++ include/uapi/linux/virtio_balloon.h | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index a1fb52cb3f0a..dfe5684000be 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -257,11 +257,13 @@ static unsigned int update_balloon_stats(struct virtio_balloon *vb) struct sysinfo i; unsigned int idx = 0; long available; + unsigned long caches; all_vm_events(events); si_meminfo(&i); available = si_mem_available(); + caches = global_node_page_state(NR_FILE_PAGES); #ifdef CONFIG_VM_EVENT_COUNTERS update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_IN, @@ -277,6 +279,8 @@ static unsigned int update_balloon_stats(struct virtio_balloon *vb) pages_to_bytes(i.totalram)); update_stat(vb, idx++, VIRTIO_BALLOON_S_AVAIL, pages_to_bytes(available)); + update_stat(vb, idx++, VIRTIO_BALLOON_S_CACHES, + pages_to_bytes(caches)); return idx; } diff --git a/include/uapi/linux/virtio_balloon.h b/include/uapi/linux/virtio_balloon.h index 343d7ddefe04..4e8b8304b793 100644 --- a/include/uapi/linux/virtio_balloon.h +++ b/include/uapi/linux/virtio_balloon.h @@ -52,7 +52,8 @@ struct virtio_balloon_config { #define VIRTIO_BALLOON_S_MEMFREE 4 /* Total amount of free memory */ #define VIRTIO_BALLOON_S_MEMTOT 5 /* Total amount of memory */ #define VIRTIO_BALLOON_S_AVAIL 6 /* Available memory as in /proc */ -#define VIRTIO_BALLOON_S_NR 7 +#define VIRTIO_BALLOON_S_CACHES 7 /* Disk caches */ +#define VIRTIO_BALLOON_S_NR 8 /* * Memory statistics structure. -- cgit v1.2.3 From 473f0b15a4c97d398387965b7eb56939543d6091 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 20 May 2017 13:48:44 +0200 Subject: vhost/scsi: Improve a size determination in four functions Replace the specification of four data structures by pointer dereferences as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention. Signed-off-by: Markus Elfring Reviewed-by: Stefan Hajnoczi Signed-off-by: Michael S. Tsirkin --- drivers/vhost/scsi.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 71517b3c5558..1e321e9fd59a 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -586,8 +586,7 @@ vhost_scsi_get_tag(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg, sg = cmd->tvc_sgl; prot_sg = cmd->tvc_prot_sgl; pages = cmd->tvc_upages; - memset(cmd, 0, sizeof(struct vhost_scsi_cmd)); - + memset(cmd, 0, sizeof(*cmd)); cmd->tvc_sgl = sg; cmd->tvc_prot_sgl = prot_sg; cmd->tvc_upages = pages; @@ -1725,7 +1724,7 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, return -EEXIST; } - tv_nexus = kzalloc(sizeof(struct vhost_scsi_nexus), GFP_KERNEL); + tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL); if (!tv_nexus) { mutex_unlock(&tpg->tv_tpg_mutex); pr_err("Unable to allocate struct vhost_scsi_nexus\n"); @@ -1926,7 +1925,7 @@ vhost_scsi_make_tpg(struct se_wwn *wwn, if (kstrtou16(name + 5, 10, &tpgt) || tpgt >= VHOST_SCSI_MAX_TARGET) return ERR_PTR(-EINVAL); - tpg = kzalloc(sizeof(struct vhost_scsi_tpg), GFP_KERNEL); + tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); if (!tpg) { pr_err("Unable to allocate struct vhost_scsi_tpg"); return ERR_PTR(-ENOMEM); @@ -1980,7 +1979,7 @@ vhost_scsi_make_tport(struct target_fabric_configfs *tf, /* if (vhost_scsi_parse_wwn(name, &wwpn, 1) < 0) return ERR_PTR(-EINVAL); */ - tport = kzalloc(sizeof(struct vhost_scsi_tport), GFP_KERNEL); + tport = kzalloc(sizeof(*tport), GFP_KERNEL); if (!tport) { pr_err("Unable to allocate struct vhost_scsi_tport"); return ERR_PTR(-ENOMEM); -- cgit v1.2.3 From c2c9f9bc5b830cbb63d6674b0d51a7773e54c90c Mon Sep 17 00:00:00 2001 From: Vasyl Gomonovych Date: Tue, 28 Nov 2017 16:15:47 +0100 Subject: virtio-mmio: Use PTR_ERR_OR_ZERO() Fix ptr_ret.cocci warnings: drivers/virtio/virtio_mmio.c:653:1-3: WARNING: PTR_ERR_OR_ZERO can be used Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: scripts/coccinelle/api/ptr_ret.cocci Signed-off-by: Vasyl Gomonovych Signed-off-by: Michael S. Tsirkin --- drivers/virtio/virtio_mmio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index c92131edfaba..b43ac9b8ae48 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -662,10 +662,8 @@ static int vm_cmdline_set(const char *device, pdev = platform_device_register_resndata(&vm_cmdline_parent, "virtio-mmio", vm_cmdline_id++, resources, ARRAY_SIZE(resources), NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - return 0; + return PTR_ERR_OR_ZERO(pdev); } static int vm_cmdline_get_device(struct device *dev, void *data) -- cgit v1.2.3 From 0a9e63aa397711cb7dd8a5c3db33448740a0b844 Mon Sep 17 00:00:00 2001 From: Vasyl Gomonovych Date: Tue, 28 Nov 2017 22:40:27 +0100 Subject: firmware: Use PTR_ERR_OR_ZERO() Fix ptr_ret.cocci warnings: drivers/firmware/efi/efi.c:610:8-14: WARNING: PTR_ERR_OR_ZERO can be used Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR Generated by: scripts/coccinelle/api/ptr_ret.cocci Signed-off-by: Vasyl Gomonovych Signed-off-by: Michael S. Tsirkin Acked-by: Gabriel Somlo Reviewed-by: Stefan Hajnoczi --- drivers/firmware/qemu_fw_cfg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index deb483064f53..a41b572eeeb1 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -694,10 +694,8 @@ static int fw_cfg_cmdline_set(const char *arg, const struct kernel_param *kp) */ fw_cfg_cmdline_dev = platform_device_register_simple("fw_cfg", PLATFORM_DEVID_NONE, res, processed); - if (IS_ERR(fw_cfg_cmdline_dev)) - return PTR_ERR(fw_cfg_cmdline_dev); - return 0; + return PTR_ERR_OR_ZERO(fw_cfg_cmdline_dev); } static int fw_cfg_cmdline_get(char *buf, const struct kernel_param *kp) -- cgit v1.2.3 From 31919140ff8c88c236f697baa28a6305df45e4ea Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Mon, 19 Jun 2017 11:44:41 +0530 Subject: virtio: virtio_mmio: make of_device_ids const. of_device_ids are not supposed to change at runtime. All functions working with of_device_ids provided by work with const of_device_ids. So mark the non-const structs as const. File size before: text data bss dec hex filename 3647 608 0 4255 109f drivers/virtio/virtio_mmio.o File size after constify virtio_mmio_match. text data bss dec hex filename 4063 192 0 4255 109f drivers/virtio/virtio_mmio.o Signed-off-by: Arvind Yadav Signed-off-by: Michael S. Tsirkin --- drivers/virtio/virtio_mmio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index b43ac9b8ae48..67763d3c7abf 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -723,7 +723,7 @@ static void vm_unregister_cmdline_devices(void) /* Platform driver */ -static struct of_device_id virtio_mmio_match[] = { +static const struct of_device_id virtio_mmio_match[] = { { .compatible = "virtio,mmio", }, {}, }; -- cgit v1.2.3 From f229a55c31a7e12a15c7b4dcf9a97a9bf7a72ce8 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 26 Oct 2017 04:48:01 +0300 Subject: virtio/ringtest: fix up need_event math last kicked event index must be updated unconditionally: even if we don't need to kick, we do not want to re-check the same entry for events. Signed-off-by: Michael S. Tsirkin Acked-by: Cornelia Huck Acked-by: Jason Wang --- tools/virtio/ringtest/ring.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/tools/virtio/ringtest/ring.c b/tools/virtio/ringtest/ring.c index 747c5dd47be8..2b9859beea65 100644 --- a/tools/virtio/ringtest/ring.c +++ b/tools/virtio/ringtest/ring.c @@ -188,16 +188,18 @@ bool enable_call() void kick_available(void) { + bool need; + /* Flush in previous flags write */ /* Barrier C (for pairing) */ smp_mb(); - if (!need_event(event->kick_index, - guest.avail_idx, - guest.kicked_avail_idx)) - return; + need = need_event(event->kick_index, + guest.avail_idx, + guest.kicked_avail_idx); guest.kicked_avail_idx = guest.avail_idx; - kick(); + if (need) + kick(); } /* host side */ @@ -253,14 +255,18 @@ bool use_buf(unsigned *lenp, void **bufp) void call_used(void) { + bool need; + /* Flush in previous flags write */ /* Barrier D (for pairing) */ smp_mb(); - if (!need_event(event->call_index, + + need = need_event(event->call_index, host.used_idx, - host.called_used_idx)) - return; + host.called_used_idx); host.called_used_idx = host.used_idx; - call(); + + if (need) + call(); } -- cgit v1.2.3 From a311650ae6ad0c169ade2583f78aa519878ea13f Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Fri, 27 Oct 2017 16:11:13 +0300 Subject: virtio/ringtest: virtio_ring: fix up need_event math last kicked event index must be updated unconditionally: even if we don't need to kick, we do not want to re-check the same entry for events. Reported-by: Cornelia Huck Signed-off-by: Michael S. Tsirkin Reviewed-by: Jens Freimann --- tools/virtio/ringtest/virtio_ring_0_9.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/tools/virtio/ringtest/virtio_ring_0_9.c b/tools/virtio/ringtest/virtio_ring_0_9.c index bbc3043b2fb1..5fd3fbcb9e57 100644 --- a/tools/virtio/ringtest/virtio_ring_0_9.c +++ b/tools/virtio/ringtest/virtio_ring_0_9.c @@ -225,16 +225,18 @@ bool enable_call() void kick_available(void) { + bool need; + /* Flush in previous flags write */ /* Barrier C (for pairing) */ smp_mb(); - if (!vring_need_event(vring_avail_event(&ring), - guest.avail_idx, - guest.kicked_avail_idx)) - return; + need = vring_need_event(vring_avail_event(&ring), + guest.avail_idx, + guest.kicked_avail_idx); guest.kicked_avail_idx = guest.avail_idx; - kick(); + if (need) + kick(); } /* host side */ @@ -316,14 +318,16 @@ bool use_buf(unsigned *lenp, void **bufp) void call_used(void) { + bool need; + /* Flush in previous flags write */ /* Barrier D (for pairing) */ smp_mb(); - if (!vring_need_event(vring_used_event(&ring), - host.used_idx, - host.called_used_idx)) - return; + need = vring_need_event(vring_used_event(&ring), + host.used_idx, + host.called_used_idx); host.called_used_idx = host.used_idx; - call(); + if (need) + call(); } -- cgit v1.2.3 From 7b95fec6d2ffa53f4a8d637b0f223644d458ea4e Mon Sep 17 00:00:00 2001 From: Vincent Legoll Date: Sun, 7 Jan 2018 12:33:56 +0100 Subject: virtio: make VIRTIO a menuconfig to ease disabling it all No need to get into the submenu to disable all VIRTIO-related config entries. This makes it easier to disable all VIRTIO config options without entering the submenu. It will also enable one to see that en/dis-abled state from the outside menu. This is only intended to change menuconfig UI, not change the config dependencies. Signed-off-by: Vincent Legoll Reviewed-by: Randy Dunlap Tested-by: Randy Dunlap Signed-off-by: Michael S. Tsirkin --- drivers/virtio/Kconfig | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index cff773f15b7e..35897649c24f 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -5,7 +5,11 @@ config VIRTIO bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_RPMSG or CONFIG_S390_GUEST. -menu "Virtio drivers" +menuconfig VIRTIO_MENU + bool "Virtio drivers" + default y + +if VIRTIO_MENU config VIRTIO_PCI tristate "PCI driver for virtio devices" @@ -79,4 +83,4 @@ config VIRTIO_MMIO_CMDLINE_DEVICES If unsure, say 'N'. -endmenu +endif # VIRTIO_MENU -- cgit v1.2.3 From daf2a5016983a1a533417bcdc729bd2b19af1b68 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 3 Jan 2018 16:03:39 +0000 Subject: virtio_blk: print capacity at probe time Print the capacity of the block device when the driver is probed. Many users expect this since SCSI disks (sd) do it. Moreover, kernel dmesg output is the primary source of troubleshooting information so it's helpful to include the disk size there. The capacity is already printed by virtio_blk when a resize event occurs. Extract the code and reuse it from virtblk_probe(). This patch also adds the block device name to the message so it can be correlated with a specific device: virtio_blk virtio0: [vda] 20971520 512-byte logical blocks (10.7 GB/10.0 GiB) Cc: Rodrigo A B Freire Cc: Michael S. Tsirkin Signed-off-by: Stefan Hajnoczi Signed-off-by: Michael S. Tsirkin --- drivers/block/virtio_blk.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 68846897d213..787cd2a10b0b 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -373,14 +373,12 @@ static ssize_t virtblk_serial_show(struct device *dev, static DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL); -static void virtblk_config_changed_work(struct work_struct *work) +/* The queue's logical block size must be set before calling this */ +static void virtblk_update_capacity(struct virtio_blk *vblk, bool resize) { - struct virtio_blk *vblk = - container_of(work, struct virtio_blk, config_work); struct virtio_device *vdev = vblk->vdev; struct request_queue *q = vblk->disk->queue; char cap_str_2[10], cap_str_10[10]; - char *envp[] = { "RESIZE=1", NULL }; unsigned long long nblocks; u64 capacity; @@ -402,13 +400,24 @@ static void virtblk_config_changed_work(struct work_struct *work) STRING_UNITS_10, cap_str_10, sizeof(cap_str_10)); dev_notice(&vdev->dev, - "new size: %llu %d-byte logical blocks (%s/%s)\n", + "[%s] %s%llu %d-byte logical blocks (%s/%s)\n", + vblk->disk->disk_name, + resize ? "new size: " : "", nblocks, queue_logical_block_size(q), cap_str_10, cap_str_2); set_capacity(vblk->disk, capacity); +} + +static void virtblk_config_changed_work(struct work_struct *work) +{ + struct virtio_blk *vblk = + container_of(work, struct virtio_blk, config_work); + char *envp[] = { "RESIZE=1", NULL }; + + virtblk_update_capacity(vblk, true); revalidate_disk(vblk->disk); kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp); } @@ -621,7 +630,6 @@ static int virtblk_probe(struct virtio_device *vdev) struct request_queue *q; int err, index; - u64 cap; u32 v, blk_size, sg_elems, opt_io_size; u16 min_io_size; u8 physical_block_exp, alignment_offset; @@ -719,17 +727,6 @@ static int virtblk_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO)) set_disk_ro(vblk->disk, 1); - /* Host must always specify the capacity. */ - virtio_cread(vdev, struct virtio_blk_config, capacity, &cap); - - /* If capacity is too big, truncate with warning. */ - if ((sector_t)cap != cap) { - dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n", - (unsigned long long)cap); - cap = (sector_t)-1; - } - set_capacity(vblk->disk, cap); - /* We can handle whatever the host told us to handle. */ blk_queue_max_segments(q, vblk->sg_elems-2); @@ -780,6 +777,7 @@ static int virtblk_probe(struct virtio_device *vdev) if (!err && opt_io_size) blk_queue_io_opt(q, blk_size * opt_io_size); + virtblk_update_capacity(vblk, false); virtio_device_ready(vdev); device_add_disk(&vdev->dev, vblk->disk); -- cgit v1.2.3 From ac964d7a594290e230f8c1038934692e30c76fc8 Mon Sep 17 00:00:00 2001 From: Tonghao Zhang Date: Tue, 9 Jan 2018 07:38:22 -0800 Subject: vhost: Remove the unused variable. The patch (7235acdb1) changed the way of the work flushing in which the queued seq, done seq, and the flushing are not used anymore. Then remove them now. Fixes: 7235acdb1 ("vhost: simplify work flushing") Cc: Jason Wang Signed-off-by: Tonghao Zhang Acked-by: Jason Wang Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 1 - drivers/vhost/vhost.h | 4 ---- 2 files changed, 5 deletions(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 5727b186b3ca..67fa3d153072 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -181,7 +181,6 @@ void vhost_work_init(struct vhost_work *work, vhost_work_fn_t fn) { clear_bit(VHOST_WORK_QUEUED, &work->flags); work->fn = fn; - init_waitqueue_head(&work->done); } EXPORT_SYMBOL_GPL(vhost_work_init); diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 79c6e7a60a5e..749fe13e061c 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -20,10 +20,6 @@ typedef void (*vhost_work_fn_t)(struct vhost_work *work); struct vhost_work { struct llist_node node; vhost_work_fn_t fn; - wait_queue_head_t done; - int flushing; - unsigned queue_seq; - unsigned done_seq; unsigned long flags; }; -- cgit v1.2.3 From f6f93f75afb65997f4a84aaaab59dd06a4a06c80 Mon Sep 17 00:00:00 2001 From: "夷则(Caspar)" Date: Mon, 25 Dec 2017 00:08:58 +0800 Subject: vhost: remove unused lock check flag in vhost_dev_cleanup() In commit ea5d404655ba ("vhost: fix release path lockdep checks"), Michael added a flag to check whether we should hold a lock in vhost_dev_cleanup(), however, in commit 47283bef7ed3 ("vhost: move memory pointer to VQs"), RCU operations have been replaced by mutex, we can remove the no-longer-used `locked' parameter now. Signed-off-by: Caspar Zhang Signed-off-by: Michael S. Tsirkin --- drivers/vhost/net.c | 2 +- drivers/vhost/scsi.c | 2 +- drivers/vhost/test.c | 2 +- drivers/vhost/vhost.c | 5 ++--- drivers/vhost/vhost.h | 2 +- drivers/vhost/vsock.c | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index c7bdeb655646..a354d8d731e3 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -996,7 +996,7 @@ static int vhost_net_release(struct inode *inode, struct file *f) vhost_net_stop(n, &tx_sock, &rx_sock); vhost_net_flush(n); vhost_dev_stop(&n->dev); - vhost_dev_cleanup(&n->dev, false); + vhost_dev_cleanup(&n->dev); vhost_net_vq_reset(n); if (tx_sock) sockfd_put(tx_sock); diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 1e321e9fd59a..7ad57094d736 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -1419,7 +1419,7 @@ static int vhost_scsi_release(struct inode *inode, struct file *f) mutex_unlock(&vs->dev.mutex); vhost_scsi_clear_endpoint(vs, &t); vhost_dev_stop(&vs->dev); - vhost_dev_cleanup(&vs->dev, false); + vhost_dev_cleanup(&vs->dev); /* Jobs can re-queue themselves in evt kick handler. Do extra flush. */ vhost_scsi_flush(vs); kfree(vs->dev.vqs); diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index 3cc98c07dcd3..906b8f0f19f7 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c @@ -157,7 +157,7 @@ static int vhost_test_release(struct inode *inode, struct file *f) vhost_test_stop(n, &private); vhost_test_flush(n); - vhost_dev_cleanup(&n->dev, false); + vhost_dev_cleanup(&n->dev); /* We do an extra flush before freeing memory, * since jobs can re-queue themselves. */ vhost_test_flush(n); diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 67fa3d153072..e5eba5acfd55 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -543,7 +543,7 @@ void vhost_dev_reset_owner(struct vhost_dev *dev, struct vhost_umem *umem) { int i; - vhost_dev_cleanup(dev, true); + vhost_dev_cleanup(dev); /* Restore memory to default empty mapping. */ INIT_LIST_HEAD(&umem->umem_list); @@ -610,8 +610,7 @@ static void vhost_clear_msg(struct vhost_dev *dev) spin_unlock(&dev->iotlb_lock); } -/* Caller should have device mutex if and only if locked is set */ -void vhost_dev_cleanup(struct vhost_dev *dev, bool locked) +void vhost_dev_cleanup(struct vhost_dev *dev) { int i; diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 749fe13e061c..d56b711577eb 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -177,7 +177,7 @@ bool vhost_dev_has_owner(struct vhost_dev *dev); long vhost_dev_check_owner(struct vhost_dev *); struct vhost_umem *vhost_dev_reset_owner_prepare(void); void vhost_dev_reset_owner(struct vhost_dev *, struct vhost_umem *); -void vhost_dev_cleanup(struct vhost_dev *, bool locked); +void vhost_dev_cleanup(struct vhost_dev *); void vhost_dev_stop(struct vhost_dev *); long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, void __user *argp); long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp); diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 5a5e981bd8e4..0d14e2ff19f1 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -599,7 +599,7 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file) } spin_unlock_bh(&vsock->send_pkt_list_lock); - vhost_dev_cleanup(&vsock->dev, false); + vhost_dev_cleanup(&vsock->dev); kfree(vsock->dev.vqs); vhost_vsock_free(vsock); return 0; -- cgit v1.2.3 From f2b44cde7e1687ef7886831a3a30df653bda2481 Mon Sep 17 00:00:00 2001 From: weiping zhang Date: Thu, 21 Dec 2017 20:39:50 +0800 Subject: virtio: split device_register into device_initialize and device_add In order to make caller do a simple cleanup, we split device_register into device_initialize and device_add. device_initialize always succeeds, so the caller can always use put_device when register_virtio_device faild. Signed-off-by: weiping zhang Suggested-by: Cornelia Huck Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck --- drivers/virtio/virtio.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index bf7ff3934d7f..59e36ef4920f 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -303,11 +303,21 @@ void unregister_virtio_driver(struct virtio_driver *driver) } EXPORT_SYMBOL_GPL(unregister_virtio_driver); +/** + * register_virtio_device - register virtio device + * @dev : virtio device to be registered + * + * On error, the caller must call put_device on &@dev->dev (and not kfree), + * as another code path may have obtained a reference to @dev. + * + * Returns: 0 on suceess, -error on failure + */ int register_virtio_device(struct virtio_device *dev) { int err; dev->dev.bus = &virtio_bus; + device_initialize(&dev->dev); /* Assign a unique device index and hence name. */ err = ida_simple_get(&virtio_index_ida, 0, 0, GFP_KERNEL); @@ -330,9 +340,11 @@ int register_virtio_device(struct virtio_device *dev) INIT_LIST_HEAD(&dev->vqs); - /* device_register() causes the bus infrastructure to look for a - * matching driver. */ - err = device_register(&dev->dev); + /* + * device_add() causes the bus infrastructure to look for a matching + * driver. + */ + err = device_add(&dev->dev); if (err) ida_simple_remove(&virtio_index_ida, dev->index); out: -- cgit v1.2.3 From 33635bd976fb4c3ccf0cfbb81a8d29bb87760607 Mon Sep 17 00:00:00 2001 From: weiping zhang Date: Thu, 21 Dec 2017 20:40:24 +0800 Subject: virtio_pci: don't kfree device on register failure As mentioned at drivers/base/core.c: /* * NOTE: _Never_ directly free @dev after calling this function, even * if it returned an error! Always use put_device() to give up the * reference initialized in this function instead. */ so we don't free vp_dev until vp_dev->vdev.dev.release be called. Signed-off-by: weiping zhang Reviewed-by: Cornelia Huck Signed-off-by: Michael S. Tsirkin --- drivers/virtio/virtio_pci_common.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 1c4797e53f68..48d4d1cf1cb6 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -513,7 +513,7 @@ static void virtio_pci_release_dev(struct device *_d) static int virtio_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) { - struct virtio_pci_device *vp_dev; + struct virtio_pci_device *vp_dev, *reg_dev = NULL; int rc; /* allocate our structure and fill it out */ @@ -551,6 +551,7 @@ static int virtio_pci_probe(struct pci_dev *pci_dev, pci_set_master(pci_dev); rc = register_virtio_device(&vp_dev->vdev); + reg_dev = vp_dev; if (rc) goto err_register; @@ -564,7 +565,10 @@ err_register: err_probe: pci_disable_device(pci_dev); err_enable_device: - kfree(vp_dev); + if (reg_dev) + put_device(&vp_dev->vdev.dev); + else + kfree(vp_dev); return rc; } -- cgit v1.2.3 From 0063e8bbd2b62d13645d416625478c2199fdee0f Mon Sep 17 00:00:00 2001 From: weiping zhang Date: Thu, 21 Dec 2017 20:40:43 +0800 Subject: virtio_vop: don't kfree device on register failure As mentioned at drivers/base/core.c: /* * NOTE: _Never_ directly free @dev after calling this function, even * if it returned an error! Always use put_device() to give up the * reference initialized in this function instead. */ so we don't free vdev until vdev->vdev.dev.release be called. Signed-off-by: weiping zhang Reviewed-by: Cornelia Huck Signed-off-by: Michael S. Tsirkin --- drivers/misc/mic/vop/vop_main.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/misc/mic/vop/vop_main.c b/drivers/misc/mic/vop/vop_main.c index a341938c7e2c..3633202e18f4 100644 --- a/drivers/misc/mic/vop/vop_main.c +++ b/drivers/misc/mic/vop/vop_main.c @@ -452,10 +452,12 @@ static irqreturn_t vop_virtio_intr_handler(int irq, void *data) static void vop_virtio_release_dev(struct device *_d) { - /* - * No need for a release method similar to virtio PCI. - * Provide an empty one to avoid getting a warning from core. - */ + struct virtio_device *vdev = + container_of(_d, struct virtio_device, dev); + struct _vop_vdev *vop_vdev = + container_of(vdev, struct _vop_vdev, vdev); + + kfree(vop_vdev); } /* @@ -466,7 +468,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d, unsigned int offset, struct vop_device *vpdev, int dnode) { - struct _vop_vdev *vdev; + struct _vop_vdev *vdev, *reg_dev = NULL; int ret; u8 type = ioread8(&d->type); @@ -497,6 +499,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d, vdev->c2h_vdev_db = ioread8(&vdev->dc->c2h_vdev_db); ret = register_virtio_device(&vdev->vdev); + reg_dev = vdev; if (ret) { dev_err(_vop_dev(vdev), "Failed to register vop device %u type %u\n", @@ -512,7 +515,10 @@ static int _vop_add_device(struct mic_device_desc __iomem *d, free_irq: vpdev->hw_ops->free_irq(vpdev, vdev->virtio_cookie, vdev); kfree: - kfree(vdev); + if (reg_dev) + put_device(&vdev->vdev.dev); + else + kfree(vdev); return ret; } @@ -568,7 +574,7 @@ static int _vop_remove_device(struct mic_device_desc __iomem *d, iowrite8(-1, &dc->h2c_vdev_db); if (status & VIRTIO_CONFIG_S_DRIVER_OK) wait_for_completion(&vdev->reset_done); - kfree(vdev); + put_device(&vdev->vdev.dev); iowrite8(1, &dc->guest_ack); dev_dbg(&vpdev->dev, "%s %d guest_ack %d\n", __func__, __LINE__, ioread8(&dc->guest_ack)); -- cgit v1.2.3 From 03ee47ae8a7c608975be7e45287bff0482e295d6 Mon Sep 17 00:00:00 2001 From: Peter Malone Date: Thu, 16 Feb 2017 15:42:26 -0500 Subject: ringtest: ring.c malloc & memset to calloc Code cleanup change - moving from malloc & memset to calloc. Signed-off-by: Peter Malone Signed-off-by: Michael S. Tsirkin --- tools/virtio/ringtest/ring.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/virtio/ringtest/ring.c b/tools/virtio/ringtest/ring.c index 2b9859beea65..5a41404aaef5 100644 --- a/tools/virtio/ringtest/ring.c +++ b/tools/virtio/ringtest/ring.c @@ -84,12 +84,11 @@ void alloc_ring(void) perror("Unable to allocate ring buffer.\n"); exit(3); } - event = malloc(sizeof *event); + event = calloc(1, sizeof(*event)); if (!event) { perror("Unable to allocate event buffer.\n"); exit(3); } - memset(event, 0, sizeof *event); guest.avail_idx = 0; guest.kicked_avail_idx = -1; guest.last_used_idx = 0; @@ -102,12 +101,11 @@ void alloc_ring(void) ring[i] = desc; } guest.num_free = ring_size; - data = malloc(ring_size * sizeof *data); + data = calloc(ring_size, sizeof(*data)); if (!data) { perror("Unable to allocate data buffer.\n"); exit(3); } - memset(data, 0, ring_size * sizeof *data); } /* guest side */ -- cgit v1.2.3 From e050c7d93f4adb2a651711e2d4e0a86d41b9d76f Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 6 Jan 2018 14:52:19 -0800 Subject: vhost: don't hold onto file pointer for VHOST_SET_VRING_CALL We already hold a reference to the eventfd_ctx, which is sufficient; there's no need to hold a reference to the struct file as well. So get rid of vhost_virtqueue->call. Signed-off-by: Eric Biggers Signed-off-by: Michael S. Tsirkin Reviewed-by: Jason Wang --- drivers/vhost/vhost.c | 20 +++++--------------- drivers/vhost/vhost.h | 1 - 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index e5eba5acfd55..7bf0b734ae70 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -321,7 +321,6 @@ static void vhost_vq_reset(struct vhost_dev *dev, vq->error = NULL; vq->kick = NULL; vq->call_ctx = NULL; - vq->call = NULL; vq->log_ctx = NULL; vhost_reset_is_le(vq); vhost_disable_cross_endian(vq); @@ -623,8 +622,6 @@ void vhost_dev_cleanup(struct vhost_dev *dev) fput(dev->vqs[i]->kick); if (dev->vqs[i]->call_ctx) eventfd_ctx_put(dev->vqs[i]->call_ctx); - if (dev->vqs[i]->call) - fput(dev->vqs[i]->call); vhost_vq_reset(dev, dev->vqs[i]); } vhost_dev_free_iovecs(dev); @@ -1490,19 +1487,12 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp) r = -EFAULT; break; } - eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); - if (IS_ERR(eventfp)) { - r = PTR_ERR(eventfp); + ctx = f.fd == -1 ? NULL : eventfd_ctx_fdget(f.fd); + if (IS_ERR(ctx)) { + r = PTR_ERR(ctx); break; } - if (eventfp != vq->call) { - filep = vq->call; - ctx = vq->call_ctx; - vq->call = eventfp; - vq->call_ctx = eventfp ? - eventfd_ctx_fileget(eventfp) : NULL; - } else - filep = eventfp; + swap(ctx, vq->call_ctx); break; case VHOST_SET_VRING_ERR: if (copy_from_user(&f, argp, sizeof f)) { @@ -1549,7 +1539,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp) if (pollstop && vq->handle_kick) vhost_poll_stop(&vq->poll); - if (ctx) + if (!IS_ERR_OR_NULL(ctx)) eventfd_ctx_put(ctx); if (filep) fput(filep); diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index d56b711577eb..0ba877e385ac 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -92,7 +92,6 @@ struct vhost_virtqueue { struct vring_used __user *used; const struct vhost_umem_node *meta_iotlb[VHOST_NUM_ADDRS]; struct file *kick; - struct file *call; struct file *error; struct eventfd_ctx *call_ctx; struct eventfd_ctx *error_ctx; -- cgit v1.2.3 From 09f332a589232f524b579ba4319433dcc7c0ed32 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 6 Jan 2018 14:52:20 -0800 Subject: vhost: don't hold onto file pointer for VHOST_SET_VRING_ERR We already hold a reference to the eventfd_ctx, which is sufficient; there's no need to hold a reference to the struct file as well. So get rid of vhost_virtqueue->error. Signed-off-by: Eric Biggers Signed-off-by: Michael S. Tsirkin Reviewed-by: Jason Wang --- drivers/vhost/vhost.c | 18 ++++-------------- drivers/vhost/vhost.h | 1 - 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 7bf0b734ae70..40a72d15361f 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -318,7 +318,6 @@ static void vhost_vq_reset(struct vhost_dev *dev, vq->acked_features = 0; vq->log_base = NULL; vq->error_ctx = NULL; - vq->error = NULL; vq->kick = NULL; vq->call_ctx = NULL; vq->log_ctx = NULL; @@ -616,8 +615,6 @@ void vhost_dev_cleanup(struct vhost_dev *dev) for (i = 0; i < dev->nvqs; ++i) { if (dev->vqs[i]->error_ctx) eventfd_ctx_put(dev->vqs[i]->error_ctx); - if (dev->vqs[i]->error) - fput(dev->vqs[i]->error); if (dev->vqs[i]->kick) fput(dev->vqs[i]->kick); if (dev->vqs[i]->call_ctx) @@ -1499,19 +1496,12 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp) r = -EFAULT; break; } - eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); - if (IS_ERR(eventfp)) { - r = PTR_ERR(eventfp); + ctx = f.fd == -1 ? NULL : eventfd_ctx_fdget(f.fd); + if (IS_ERR(ctx)) { + r = PTR_ERR(ctx); break; } - if (eventfp != vq->error) { - filep = vq->error; - vq->error = eventfp; - ctx = vq->error_ctx; - vq->error_ctx = eventfp ? - eventfd_ctx_fileget(eventfp) : NULL; - } else - filep = eventfp; + swap(ctx, vq->error_ctx); break; case VHOST_SET_VRING_ENDIAN: r = vhost_set_vring_endian(vq, argp); diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 0ba877e385ac..e3c463ce3d48 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -92,7 +92,6 @@ struct vhost_virtqueue { struct vring_used __user *used; const struct vhost_umem_node *meta_iotlb[VHOST_NUM_ADDRS]; struct file *kick; - struct file *error; struct eventfd_ctx *call_ctx; struct eventfd_ctx *error_ctx; struct eventfd_ctx *log_ctx; -- cgit v1.2.3 From d25cc43c6775bff6b8e3dad97c747954b805e421 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 6 Jan 2018 14:52:21 -0800 Subject: vhost: don't hold onto file pointer for VHOST_SET_LOG_FD We already hold a reference to the eventfd_ctx, which is sufficient; there's no need to hold a reference to the struct file as well. So get rid of vhost_dev->log_file. Signed-off-by: Eric Biggers Signed-off-by: Michael S. Tsirkin Reviewed-by: Jason Wang --- drivers/vhost/vhost.c | 24 +++++------------------- drivers/vhost/vhost.h | 1 - 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 40a72d15361f..66775446248a 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -419,7 +419,6 @@ void vhost_dev_init(struct vhost_dev *dev, dev->nvqs = nvqs; mutex_init(&dev->mutex); dev->log_ctx = NULL; - dev->log_file = NULL; dev->umem = NULL; dev->iotlb = NULL; dev->mm = NULL; @@ -625,9 +624,6 @@ void vhost_dev_cleanup(struct vhost_dev *dev) if (dev->log_ctx) eventfd_ctx_put(dev->log_ctx); dev->log_ctx = NULL; - if (dev->log_file) - fput(dev->log_file); - dev->log_file = NULL; /* No one will access memory at this point */ vhost_umem_clean(dev->umem); dev->umem = NULL; @@ -1572,8 +1568,7 @@ EXPORT_SYMBOL_GPL(vhost_init_device_iotlb); /* Caller must have device mutex */ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp) { - struct file *eventfp, *filep = NULL; - struct eventfd_ctx *ctx = NULL; + struct eventfd_ctx *ctx; u64 p; long r; int i, fd; @@ -1619,19 +1614,12 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp) r = get_user(fd, (int __user *)argp); if (r < 0) break; - eventfp = fd == -1 ? NULL : eventfd_fget(fd); - if (IS_ERR(eventfp)) { - r = PTR_ERR(eventfp); + ctx = fd == -1 ? NULL : eventfd_ctx_fdget(fd); + if (IS_ERR(ctx)) { + r = PTR_ERR(ctx); break; } - if (eventfp != d->log_file) { - filep = d->log_file; - d->log_file = eventfp; - ctx = d->log_ctx; - d->log_ctx = eventfp ? - eventfd_ctx_fileget(eventfp) : NULL; - } else - filep = eventfp; + swap(ctx, d->log_ctx); for (i = 0; i < d->nvqs; ++i) { mutex_lock(&d->vqs[i]->mutex); d->vqs[i]->log_ctx = d->log_ctx; @@ -1639,8 +1627,6 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp) } if (ctx) eventfd_ctx_put(ctx); - if (filep) - fput(filep); break; default: r = -ENOIOCTLCMD; diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index e3c463ce3d48..45d12b01cfe4 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -157,7 +157,6 @@ struct vhost_dev { struct mutex mutex; struct vhost_virtqueue **vqs; int nvqs; - struct file *log_file; struct eventfd_ctx *log_ctx; struct llist_head work_list; struct task_struct *worker; -- cgit v1.2.3