From 61a734d305e16944b42730ef582a7171dc733321 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Mon, 18 Aug 2014 10:41:36 +0100 Subject: xen/manage: Always freeze/thaw processes when suspend/resuming Always freeze processes when suspending and thaw processes when resuming to prevent a race noticeable with HVM guests. This prevents a deadlock where the khubd kthread (which is designed to be freezable) acquires a usb device lock and then tries to allocate memory which requires the disk which hasn't been resumed yet. Meanwhile, the xenwatch thread deadlocks waiting for the usb device lock. Freezing processes fixes this because the khubd thread is only thawed after the xenwatch thread finishes resuming all the devices. Signed-off-by: Ross Lagerwall Signed-off-by: David Vrabel Cc: stable@vger.kernel.org --- drivers/xen/manage.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 5f1e1f3cd186..f8bb36f9d9ce 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -103,16 +103,11 @@ static void do_suspend(void) shutting_down = SHUTDOWN_SUSPEND; -#ifdef CONFIG_PREEMPT - /* If the kernel is preemptible, we need to freeze all the processes - to prevent them from being in the middle of a pagetable update - during suspend. */ err = freeze_processes(); if (err) { pr_err("%s: freeze failed %d\n", __func__, err); goto out; } -#endif err = dpm_suspend_start(PMSG_FREEZE); if (err) { @@ -157,10 +152,8 @@ out_resume: dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE); out_thaw: -#ifdef CONFIG_PREEMPT thaw_processes(); out: -#endif shutting_down = SHUTDOWN_INVALID; } #endif /* CONFIG_HIBERNATE_CALLBACKS */ -- cgit v1.2.1 From 3dcf63677d4eb7fdfc13290c8558c301d2588fe8 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Mon, 1 Sep 2014 18:52:44 +0100 Subject: xen/balloon: cancel ballooning if adding new memory failed If the balloon driver is adding additional memory regions to the balloon and add_memory() fails it will likely continuously fail so cancel the balloon operation. Signed-off-by: David Vrabel Reviewed-by: Daniel Kiper --- drivers/xen/balloon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 5c660c77f03b..1e0a317d3dcd 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -230,8 +230,8 @@ static enum bp_state reserve_additional_memory(long credit) rc = add_memory(nid, hotplug_start_paddr, balloon_hotplug << PAGE_SHIFT); if (rc) { - pr_info("%s: add_memory() failed: %i\n", __func__, rc); - return BP_EAGAIN; + pr_warn("Cannot add additional memory (%i)\n", rc); + return BP_ECANCELED; } balloon_hotplug -= credit; -- cgit v1.2.1 From e9de2e5fd602c4f5ddf212d3837b19ad4f5878ad Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Tue, 2 Sep 2014 15:21:29 +0100 Subject: xen/gntalloc: fix oops after runnning out of grant refs Only set gref->gref_id if foreign access was successfully granted and the grant ref is valid. If gref->gref_id == -ENOSPC the test in __del_gref() would incorrectly attempt to end foreign access (because grant_ref_t is unsigned). Signed-off-by: David Vrabel Reported-by: Dave Scott Reviewed-by: Boris Ostrovsky --- drivers/xen/gntalloc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c index 787d17945418..8ed2bb4f6f21 100644 --- a/drivers/xen/gntalloc.c +++ b/drivers/xen/gntalloc.c @@ -141,13 +141,11 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op, goto undo; /* Grant foreign access to the page. */ - gref->gref_id = gnttab_grant_foreign_access(op->domid, + rc = gnttab_grant_foreign_access(op->domid, pfn_to_mfn(page_to_pfn(gref->page)), readonly); - if ((int)gref->gref_id < 0) { - rc = gref->gref_id; + if (rc < 0) goto undo; - } - gref_ids[i] = gref->gref_id; + gref_ids[i] = gref->gref_id = rc; } /* Add to gref lists. */ @@ -193,7 +191,7 @@ static void __del_gref(struct gntalloc_gref *gref) gref->notify.flags = 0; - if (gref->gref_id > 0) { + if (gref->gref_id) { if (gnttab_query_foreign_access(gref->gref_id)) return; -- cgit v1.2.1 From 5903c6bd1a48d90b99e207ec2a6a7673cbbb732d Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Tue, 2 Sep 2014 15:21:30 +0100 Subject: xen/gntalloc: safely delete grefs in add_grefs() undo path If a gref could not be added (perhaps because the limit has been reached or there are no more grant references available), the undo path may crash because __del_gref() frees the gref while it is being used for a list iteration. A comment suggests that using list_for_each_entry() is safe since the gref isn't removed from the list being iterated over, but it is freed and thus list_for_each_entry_safe() must be used. Also, explicitly delete the gref from the local per-file list, even though this is not strictly necessary. Signed-off-by: David Vrabel Reviewed-by: Boris Ostrovsky --- drivers/xen/gntalloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c index 8ed2bb4f6f21..e53fe191738c 100644 --- a/drivers/xen/gntalloc.c +++ b/drivers/xen/gntalloc.c @@ -124,7 +124,7 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op, int i, rc, readonly; LIST_HEAD(queue_gref); LIST_HEAD(queue_file); - struct gntalloc_gref *gref; + struct gntalloc_gref *gref, *next; readonly = !(op->flags & GNTALLOC_FLAG_WRITABLE); rc = -ENOMEM; @@ -160,8 +160,8 @@ undo: mutex_lock(&gref_mutex); gref_size -= (op->count - i); - list_for_each_entry(gref, &queue_file, next_file) { - /* __del_gref does not remove from queue_file */ + list_for_each_entry_safe(gref, next, &queue_file, next_file) { + list_del(&gref->next_file); __del_gref(gref); } -- cgit v1.2.1