aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2013-03-15 15:25:40 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-15 15:11:50 -0400
commit6571b2dab4eb6c7061160490db984dbc01e5626d (patch)
treeeababb8049da4fcb1d41e7e458228e41638ee333 /drivers/hv
parent7a64b864a0989302b5f6869f8b65b630b10bd9db (diff)
Drivers: hv: balloon: Execute balloon inflation in a separate context
Execute the balloon inflation operation in a separate work context. This allows us to decouple the pressure reporting activity from the ballooning activity. Testing has shown that this decoupling makes the guest more reponsive. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/hv_balloon.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 7fb72dd05ba2..8dc406ccf10f 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -412,6 +412,11 @@ struct dm_info_msg {
412 * End protocol definitions. 412 * End protocol definitions.
413 */ 413 */
414 414
415struct balloon_state {
416 __u32 num_pages;
417 struct work_struct wrk;
418};
419
415static bool hot_add; 420static bool hot_add;
416static bool do_hot_add; 421static bool do_hot_add;
417/* 422/*
@@ -459,7 +464,12 @@ struct hv_dynmem_device {
459 unsigned int num_pages_ballooned; 464 unsigned int num_pages_ballooned;
460 465
461 /* 466 /*
462 * This thread handles both balloon/hot-add 467 * State to manage the ballooning (up) operation.
468 */
469 struct balloon_state balloon_wrk;
470
471 /*
472 * This thread handles hot-add
463 * requests from the host as well as notifying 473 * requests from the host as well as notifying
464 * the host with regards to memory pressure in 474 * the host with regards to memory pressure in
465 * the guest. 475 * the guest.
@@ -657,9 +667,9 @@ static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
657 667
658 668
659 669
660static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req) 670static void balloon_up(struct work_struct *dummy)
661{ 671{
662 int num_pages = req->num_pages; 672 int num_pages = dm_device.balloon_wrk.num_pages;
663 int num_ballooned = 0; 673 int num_ballooned = 0;
664 struct dm_balloon_response *bl_resp; 674 struct dm_balloon_response *bl_resp;
665 int alloc_unit; 675 int alloc_unit;
@@ -684,14 +694,14 @@ static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req)
684 694
685 695
686 num_pages -= num_ballooned; 696 num_pages -= num_ballooned;
687 num_ballooned = alloc_balloon_pages(dm, num_pages, 697 num_ballooned = alloc_balloon_pages(&dm_device, num_pages,
688 bl_resp, alloc_unit, 698 bl_resp, alloc_unit,
689 &alloc_error); 699 &alloc_error);
690 700
691 if ((alloc_error) || (num_ballooned == num_pages)) { 701 if ((alloc_error) || (num_ballooned == num_pages)) {
692 bl_resp->more_pages = 0; 702 bl_resp->more_pages = 0;
693 done = true; 703 done = true;
694 dm->state = DM_INITIALIZED; 704 dm_device.state = DM_INITIALIZED;
695 } 705 }
696 706
697 /* 707 /*
@@ -719,7 +729,7 @@ static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req)
719 pr_info("Balloon response failed\n"); 729 pr_info("Balloon response failed\n");
720 730
721 for (i = 0; i < bl_resp->range_count; i++) 731 for (i = 0; i < bl_resp->range_count; i++)
722 free_balloon_pages(dm, 732 free_balloon_pages(&dm_device,
723 &bl_resp->range_array[i]); 733 &bl_resp->range_array[i]);
724 734
725 done = true; 735 done = true;
@@ -775,9 +785,6 @@ static int dm_thread_func(void *dm_dev)
775 785
776 scan_start = jiffies; 786 scan_start = jiffies;
777 switch (dm->state) { 787 switch (dm->state) {
778 case DM_BALLOON_UP:
779 balloon_up(dm, (struct dm_balloon *)recv_buffer);
780 break;
781 788
782 case DM_HOT_ADD: 789 case DM_HOT_ADD:
783 hot_add_req(dm, (struct dm_hot_add *)recv_buffer); 790 hot_add_req(dm, (struct dm_hot_add *)recv_buffer);
@@ -861,6 +868,7 @@ static void balloon_onchannelcallback(void *context)
861 struct dm_message *dm_msg; 868 struct dm_message *dm_msg;
862 struct dm_header *dm_hdr; 869 struct dm_header *dm_hdr;
863 struct hv_dynmem_device *dm = hv_get_drvdata(dev); 870 struct hv_dynmem_device *dm = hv_get_drvdata(dev);
871 struct dm_balloon *bal_msg;
864 872
865 memset(recv_buffer, 0, sizeof(recv_buffer)); 873 memset(recv_buffer, 0, sizeof(recv_buffer));
866 vmbus_recvpacket(dev->channel, recv_buffer, 874 vmbus_recvpacket(dev->channel, recv_buffer,
@@ -882,8 +890,12 @@ static void balloon_onchannelcallback(void *context)
882 break; 890 break;
883 891
884 case DM_BALLOON_REQUEST: 892 case DM_BALLOON_REQUEST:
893 if (dm->state == DM_BALLOON_UP)
894 pr_warn("Currently ballooning\n");
895 bal_msg = (struct dm_balloon *)recv_buffer;
885 dm->state = DM_BALLOON_UP; 896 dm->state = DM_BALLOON_UP;
886 complete(&dm->config_event); 897 dm_device.balloon_wrk.num_pages = bal_msg->num_pages;
898 schedule_work(&dm_device.balloon_wrk.wrk);
887 break; 899 break;
888 900
889 case DM_UNBALLOON_REQUEST: 901 case DM_UNBALLOON_REQUEST:
@@ -937,6 +949,7 @@ static int balloon_probe(struct hv_device *dev,
937 dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7; 949 dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7;
938 init_completion(&dm_device.host_event); 950 init_completion(&dm_device.host_event);
939 init_completion(&dm_device.config_event); 951 init_completion(&dm_device.config_event);
952 INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up);
940 953
941 dm_device.thread = 954 dm_device.thread =
942 kthread_run(dm_thread_func, &dm_device, "hv_balloon"); 955 kthread_run(dm_thread_func, &dm_device, "hv_balloon");
@@ -1048,6 +1061,7 @@ static int balloon_remove(struct hv_device *dev)
1048 if (dm->num_pages_ballooned != 0) 1061 if (dm->num_pages_ballooned != 0)
1049 pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned); 1062 pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned);
1050 1063
1064 cancel_work_sync(&dm->balloon_wrk.wrk);
1051 vmbus_close(dev->channel); 1065 vmbus_close(dev->channel);
1052 kthread_stop(dm->thread); 1066 kthread_stop(dm->thread);
1053 kfree(send_buffer); 1067 kfree(send_buffer);