From 3ac7292a25db1c607a50752055a18aba32ac2176 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Thu, 11 Jan 2018 09:36:37 +0000 Subject: xen/grant-table: Use put_page instead of free_page The page given to gnttab_end_foreign_access() to free could be a compound page so use put_page() instead of free_page() since it can handle both compound and single pages correctly. This bug was discovered when migrating a Xen VM with several VIFs and CONFIG_DEBUG_VM enabled. It hits a BUG usually after fewer than 10 iterations. All netfront devices disconnect from the backend during a suspend/resume and this will call gnttab_end_foreign_access() if a netfront queue has an outstanding skb. The mismatch between calling get_page() and free_page() on a compound page causes a reference counting error which is detected when DEBUG_VM is enabled. Signed-off-by: Ross Lagerwall Reviewed-by: Boris Ostrovsky Signed-off-by: Juergen Gross --- drivers/xen/grant-table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index f45114fd8e1e..27be107d6480 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -382,7 +382,7 @@ static void gnttab_handle_deferred(struct timer_list *unused) if (entry->page) { pr_debug("freeing g.e. %#x (pfn %#lx)\n", entry->ref, page_to_pfn(entry->page)); - __free_page(entry->page); + put_page(entry->page); } else pr_info("freeing g.e. %#x\n", entry->ref); kfree(entry); @@ -438,7 +438,7 @@ void gnttab_end_foreign_access(grant_ref_t ref, int readonly, if (gnttab_end_foreign_access_ref(ref, readonly)) { put_free_entry(ref); if (page != 0) - free_page(page); + put_page(virt_to_page(page)); } else gnttab_add_deferred(ref, readonly, page ? virt_to_page(page) : NULL); -- cgit v1.2.3 From 761191258839b7d922b83064c4251b8bd4e2e7c2 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 2 Feb 2018 17:34:09 -0800 Subject: pvcalls-back: do not return error on inet_accept EAGAIN When the client sends a regular blocking accept request, the backend is expected to return only when the accept is completed, simulating a blocking behavior, or return an error. Specifically, on EAGAIN from inet_accept, the backend shouldn't return "EAGAIN" to the client. Instead, it should simply continue the wait. Otherwise, the client will send another accept request, which will cause another EAGAIN to be sent back, which is a waste of resources and not conforming to the expected behavior. Change the behavior by turning the "goto error" into a return. Signed-off-by: Stefano Stabellini Reviewed-by: Boris Ostrovsky Signed-off-by: Juergen Gross --- drivers/xen/pvcalls-back.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/xen') diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c index c7822d8078b9..156e5aea36db 100644 --- a/drivers/xen/pvcalls-back.c +++ b/drivers/xen/pvcalls-back.c @@ -548,7 +548,7 @@ static void __pvcalls_back_accept(struct work_struct *work) ret = inet_accept(mappass->sock, sock, O_NONBLOCK, true); if (ret == -EAGAIN) { sock_release(sock); - goto out_error; + return; } map = pvcalls_new_active_socket(fedata, -- cgit v1.2.3