diff options
Diffstat (limited to 'drivers/misc/vmw_balloon.c')
| -rw-r--r-- | drivers/misc/vmw_balloon.c | 54 |
1 files changed, 23 insertions, 31 deletions
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 6df5a55da11..19161749218 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c @@ -17,7 +17,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * - * Maintained by: Dmitry Torokhov <dtor@vmware.com> + * Maintained by: Xavier Deguillard <xdeguillard@vmware.com> + * Philip Moltmann <moltmann@vmware.com> */ /* @@ -45,7 +46,7 @@ MODULE_AUTHOR("VMware, Inc."); MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver"); -MODULE_VERSION("1.2.1.2-k"); +MODULE_VERSION("1.2.1.3-k"); MODULE_ALIAS("dmi:*:svnVMware*:*"); MODULE_ALIAS("vmware_vmmemctl"); MODULE_LICENSE("GPL"); @@ -133,7 +134,7 @@ MODULE_LICENSE("GPL"); #define VMWARE_BALLOON_CMD(cmd, data, result) \ ({ \ unsigned long __stat, __dummy1, __dummy2; \ - __asm__ __volatile__ ("inl (%%dx)" : \ + __asm__ __volatile__ ("inl %%dx" : \ "=a"(__stat), \ "=c"(__dummy1), \ "=d"(__dummy2), \ @@ -151,7 +152,7 @@ MODULE_LICENSE("GPL"); struct vmballoon_stats { unsigned int timer; - /* allocation statustics */ + /* allocation statistics */ unsigned int alloc; unsigned int alloc_fail; unsigned int sleep_alloc; @@ -215,7 +216,6 @@ struct vmballoon { }; static struct vmballoon balloon; -static struct workqueue_struct *vmballoon_wq; /* * Send "start" command to the host, communicating supported version @@ -315,7 +315,7 @@ static bool vmballoon_send_get_target(struct vmballoon *b, u32 *new_target) * fear that guest will need it. Host may reject some pages, we need to * check the return value and maybe submit a different page. */ -static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn, +static int vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn, unsigned int *hv_status) { unsigned long status, dummy; @@ -323,17 +323,17 @@ static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn, pfn32 = (u32)pfn; if (pfn32 != pfn) - return false; + return -1; STATS_INC(b->stats.lock); *hv_status = status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy); if (vmballoon_check_status(b, status)) - return true; + return 0; pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status); STATS_INC(b->stats.lock_fail); - return false; + return 1; } /* @@ -412,7 +412,8 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep) struct page *page; gfp_t flags; unsigned int hv_status; - bool locked = false; + int locked; + flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP; do { if (!can_sleep) @@ -420,7 +421,6 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep) else STATS_INC(b->stats.sleep_alloc); - flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP; page = alloc_page(flags); if (!page) { if (!can_sleep) @@ -432,7 +432,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep) /* inform monitor */ locked = vmballoon_send_lock_page(b, page_to_pfn(page), &hv_status); - if (!locked) { + if (locked > 0) { STATS_INC(b->stats.refused_alloc); if (hv_status == VMW_BALLOON_ERROR_RESET || @@ -450,7 +450,7 @@ static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep) if (++b->n_refused_pages >= VMW_BALLOON_MAX_REFUSED) return -EIO; } - } while (!locked); + } while (locked != 0); /* track allocated page */ list_add(&page->lru, &b->pages); @@ -674,7 +674,12 @@ static void vmballoon_work(struct work_struct *work) vmballoon_deflate(b); } - queue_delayed_work(vmballoon_wq, dwork, round_jiffies_relative(HZ)); + /* + * We are using a freezable workqueue so that balloon operations are + * stopped while the system transitions to/from sleep/hibernation. + */ + queue_delayed_work(system_freezable_wq, + dwork, round_jiffies_relative(HZ)); } /* @@ -785,12 +790,6 @@ static int __init vmballoon_init(void) if (x86_hyper != &x86_hyper_vmware) return -ENODEV; - vmballoon_wq = create_freezable_workqueue("vmmemctl"); - if (!vmballoon_wq) { - pr_err("failed to create workqueue\n"); - return -ENOMEM; - } - INIT_LIST_HEAD(&balloon.pages); INIT_LIST_HEAD(&balloon.refused_pages); @@ -805,34 +804,27 @@ static int __init vmballoon_init(void) */ if (!vmballoon_send_start(&balloon)) { pr_err("failed to send start command to the host\n"); - error = -EIO; - goto fail; + return -EIO; } if (!vmballoon_send_guest_id(&balloon)) { pr_err("failed to send guest ID to the host\n"); - error = -EIO; - goto fail; + return -EIO; } error = vmballoon_debugfs_init(&balloon); if (error) - goto fail; + return error; - queue_delayed_work(vmballoon_wq, &balloon.dwork, 0); + queue_delayed_work(system_freezable_wq, &balloon.dwork, 0); return 0; - -fail: - destroy_workqueue(vmballoon_wq); - return error; } module_init(vmballoon_init); static void __exit vmballoon_exit(void) { cancel_delayed_work_sync(&balloon.dwork); - destroy_workqueue(vmballoon_wq); vmballoon_debugfs_exit(&balloon); |
