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 virtio updates from Michael Tsirkin:
 "Fixes in qemu, vhost and virtio"

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
  fw_cfg: fix the command line module name
  vhost/vsock: fix uninitialized vhost_vsock->guest_cid
  vhost: fix end of range for access_ok
  vhost/scsi: Use safe iteration in vhost_scsi_complete_cmd_work()
  virtio_balloon: fix deadlock on OOM
  • Loading branch information
torvalds committed Nov 16, 2017
2 parents 051089a + c1d0c3f commit 18c83d2
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 21 deletions.
8 changes: 4 additions & 4 deletions drivers/firmware/qemu_fw_cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
* and select subsets of aarch64), a Device Tree node (on arm), or using
* a kernel module (or command line) parameter with the following syntax:
*
* [fw_cfg.]ioport=<size>@<base>[:<ctrl_off>:<data_off>]
* [qemu_fw_cfg.]ioport=<size>@<base>[:<ctrl_off>:<data_off>]
* or
* [fw_cfg.]mmio=<size>@<base>[:<ctrl_off>:<data_off>]
* [qemu_fw_cfg.]mmio=<size>@<base>[:<ctrl_off>:<data_off>]
*
* where:
* <size> := size of ioport or mmio range
Expand All @@ -21,9 +21,9 @@
* <data_off> := (optional) offset of data register
*
* e.g.:
* fw_cfg.ioport=2@0x510:0:1 (the default on x86)
* qemu_fw_cfg.ioport=2@0x510:0:1 (the default on x86)
* or
* fw_cfg.mmio=0xA@0x9020000:8:0 (the default on arm)
* qemu_fw_cfg.mmio=0xA@0x9020000:8:0 (the default on arm)
*/

#include <linux/module.h>
Expand Down
4 changes: 2 additions & 2 deletions drivers/vhost/scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,15 +519,15 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
vs_completion_work);
DECLARE_BITMAP(signal, VHOST_SCSI_MAX_VQ);
struct virtio_scsi_cmd_resp v_rsp;
struct vhost_scsi_cmd *cmd;
struct vhost_scsi_cmd *cmd, *t;
struct llist_node *llnode;
struct se_cmd *se_cmd;
struct iov_iter iov_iter;
int ret, vq;

bitmap_zero(signal, VHOST_SCSI_MAX_VQ);
llnode = llist_del_all(&vs->vs_completion_list);
llist_for_each_entry(cmd, llnode, tvc_completion_list) {
llist_for_each_entry_safe(cmd, t, llnode, tvc_completion_list) {
se_cmd = &cmd->tvc_se_cmd;

pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__,
Expand Down
4 changes: 2 additions & 2 deletions drivers/vhost/vhost.c
Original file line number Diff line number Diff line change
Expand Up @@ -1175,15 +1175,15 @@ static int iotlb_access_ok(struct vhost_virtqueue *vq,
{
const struct vhost_umem_node *node;
struct vhost_umem *umem = vq->iotlb;
u64 s = 0, size, orig_addr = addr;
u64 s = 0, size, orig_addr = addr, last = addr + len - 1;

if (vhost_vq_meta_fetch(vq, addr, len, type))
return true;

while (len > s) {
node = vhost_umem_interval_tree_iter_first(&umem->umem_tree,
addr,
addr + len - 1);
last);
if (node == NULL || node->start > addr) {
vhost_iotlb_miss(vq, addr, access);
return false;
Expand Down
2 changes: 2 additions & 0 deletions drivers/vhost/vsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,8 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)
goto out;
}

vsock->guest_cid = 0; /* no CID assigned yet */

atomic_set(&vsock->queued_replies, 0);

vqs[VSOCK_VQ_TX] = &vsock->vqs[VSOCK_VQ_TX];
Expand Down
24 changes: 19 additions & 5 deletions drivers/virtio/virtio_balloon.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,16 +143,17 @@ static void set_page_pfns(struct virtio_balloon *vb,

static unsigned fill_balloon(struct virtio_balloon *vb, size_t num)
{
struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info;
unsigned num_allocated_pages;
unsigned num_pfns;
struct page *page;
LIST_HEAD(pages);

/* We can only do one array worth at a time. */
num = min(num, ARRAY_SIZE(vb->pfns));

mutex_lock(&vb->balloon_lock);
for (vb->num_pfns = 0; vb->num_pfns < num;
vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
struct page *page = balloon_page_enqueue(vb_dev_info);
for (num_pfns = 0; num_pfns < num;
num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
struct page *page = balloon_page_alloc();

if (!page) {
dev_info_ratelimited(&vb->vdev->dev,
Expand All @@ -162,6 +163,19 @@ static unsigned fill_balloon(struct virtio_balloon *vb, size_t num)
msleep(200);
break;
}

balloon_page_push(&pages, page);
}

mutex_lock(&vb->balloon_lock);

vb->num_pfns = 0;

while ((page = balloon_page_pop(&pages))) {
balloon_page_enqueue(&vb->vb_dev_info, page);

vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE;

set_page_pfns(vb, vb->pfns + vb->num_pfns, page);
vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE;
if (!virtio_has_feature(vb->vdev,
Expand Down
35 changes: 34 additions & 1 deletion include/linux/balloon_compaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <linux/gfp.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/list.h>

/*
* Balloon device information descriptor.
Expand All @@ -67,7 +68,9 @@ struct balloon_dev_info {
struct inode *inode;
};

extern struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info);
extern struct page *balloon_page_alloc(void);
extern void balloon_page_enqueue(struct balloon_dev_info *b_dev_info,
struct page *page);
extern struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info);

static inline void balloon_devinfo_init(struct balloon_dev_info *balloon)
Expand Down Expand Up @@ -193,4 +196,34 @@ static inline gfp_t balloon_mapping_gfp_mask(void)
}

#endif /* CONFIG_BALLOON_COMPACTION */

/*
* balloon_page_push - insert a page into a page list.
* @head : pointer to list
* @page : page to be added
*
* Caller must ensure the page is private and protect the list.
*/
static inline void balloon_page_push(struct list_head *pages, struct page *page)
{
list_add(&page->lru, pages);
}

/*
* balloon_page_pop - remove a page from a page list.
* @head : pointer to list
* @page : page to be added
*
* Caller must ensure the page is private and protect the list.
*/
static inline struct page *balloon_page_pop(struct list_head *pages)
{
struct page *page = list_first_entry_or_null(pages, struct page, lru);

if (!page)
return NULL;

list_del(&page->lru);
return page;
}
#endif /* _LINUX_BALLOON_COMPACTION_H */
28 changes: 21 additions & 7 deletions mm/balloon_compaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,38 @@
#include <linux/export.h>
#include <linux/balloon_compaction.h>

/*
* balloon_page_alloc - allocates a new page for insertion into the balloon
* page list.
*
* Driver must call it to properly allocate a new enlisted balloon page.
* Driver must call balloon_page_enqueue before definitively removing it from
* the guest system. This function returns the page address for the recently
* allocated page or NULL in the case we fail to allocate a new page this turn.
*/
struct page *balloon_page_alloc(void)
{
struct page *page = alloc_page(balloon_mapping_gfp_mask() |
__GFP_NOMEMALLOC | __GFP_NORETRY);
return page;
}
EXPORT_SYMBOL_GPL(balloon_page_alloc);

/*
* balloon_page_enqueue - allocates a new page and inserts it into the balloon
* page list.
* @b_dev_info: balloon device descriptor where we will insert a new page to
* @page: new page to enqueue - allocated using balloon_page_alloc.
*
* Driver must call it to properly allocate a new enlisted balloon page
* Driver must call it to properly enqueue a new allocated balloon page
* before definitively removing it from the guest system.
* This function returns the page address for the recently enqueued page or
* NULL in the case we fail to allocate a new page this turn.
*/
struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info)
void balloon_page_enqueue(struct balloon_dev_info *b_dev_info,
struct page *page)
{
unsigned long flags;
struct page *page = alloc_page(balloon_mapping_gfp_mask() |
__GFP_NOMEMALLOC | __GFP_NORETRY);
if (!page)
return NULL;

/*
* Block others from accessing the 'page' when we get around to
Expand All @@ -39,7 +54,6 @@ struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info)
__count_vm_event(BALLOON_INFLATE);
spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
unlock_page(page);
return page;
}
EXPORT_SYMBOL_GPL(balloon_page_enqueue);

Expand Down

0 comments on commit 18c83d2

Please sign in to comment.