aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2013-03-15 15:25:41 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-15 15:11:50 -0400
commitc51af826cf062af3c49a99a05a33236d93c57e72 (patch)
treef1f61f8e04b17a16820d61a311059cc6a6efaec6 /drivers/hv
parent6571b2dab4eb6c7061160490db984dbc01e5626d (diff)
Drivers: hv: balloon: Execute hot-add code in a separate context
Execute the hot-add operation in a separate work context. This allows us to decouple the pressure reporting activity from the "hot-add" activity. Testing has shown that this makes the guest more responsive to hot add requests. 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.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 8dc406ccf10f..13fda3807bfb 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -417,6 +417,11 @@ struct balloon_state {
417 struct work_struct wrk; 417 struct work_struct wrk;
418}; 418};
419 419
420struct hot_add_wrk {
421 union dm_mem_page_range ha_page_range;
422 struct work_struct wrk;
423};
424
420static bool hot_add; 425static bool hot_add;
421static bool do_hot_add; 426static bool do_hot_add;
422/* 427/*
@@ -469,6 +474,11 @@ struct hv_dynmem_device {
469 struct balloon_state balloon_wrk; 474 struct balloon_state balloon_wrk;
470 475
471 /* 476 /*
477 * State to execute the "hot-add" operation.
478 */
479 struct hot_add_wrk ha_wrk;
480
481 /*
472 * This thread handles hot-add 482 * This thread handles hot-add
473 * requests from the host as well as notifying 483 * requests from the host as well as notifying
474 * the host with regards to memory pressure in 484 * the host with regards to memory pressure in
@@ -486,7 +496,7 @@ struct hv_dynmem_device {
486 496
487static struct hv_dynmem_device dm_device; 497static struct hv_dynmem_device dm_device;
488 498
489static void hot_add_req(struct hv_dynmem_device *dm, struct dm_hot_add *msg) 499static void hot_add_req(struct work_struct *dummy)
490{ 500{
491 501
492 struct dm_hot_add_response resp; 502 struct dm_hot_add_response resp;
@@ -509,8 +519,8 @@ static void hot_add_req(struct hv_dynmem_device *dm, struct dm_hot_add *msg)
509 resp.page_count = 0; 519 resp.page_count = 0;
510 resp.result = 0; 520 resp.result = 0;
511 521
512 dm->state = DM_INITIALIZED; 522 dm_device.state = DM_INITIALIZED;
513 vmbus_sendpacket(dm->dev->channel, &resp, 523 vmbus_sendpacket(dm_device.dev->channel, &resp,
514 sizeof(struct dm_hot_add_response), 524 sizeof(struct dm_hot_add_response),
515 (unsigned long)NULL, 525 (unsigned long)NULL,
516 VM_PKT_DATA_INBAND, 0); 526 VM_PKT_DATA_INBAND, 0);
@@ -771,7 +781,6 @@ static int dm_thread_func(void *dm_dev)
771{ 781{
772 struct hv_dynmem_device *dm = dm_dev; 782 struct hv_dynmem_device *dm = dm_dev;
773 int t; 783 int t;
774 unsigned long scan_start;
775 784
776 while (!kthread_should_stop()) { 785 while (!kthread_should_stop()) {
777 t = wait_for_completion_timeout(&dm_device.config_event, 1*HZ); 786 t = wait_for_completion_timeout(&dm_device.config_event, 1*HZ);
@@ -783,19 +792,6 @@ static int dm_thread_func(void *dm_dev)
783 if (t == 0) 792 if (t == 0)
784 post_status(dm); 793 post_status(dm);
785 794
786 scan_start = jiffies;
787 switch (dm->state) {
788
789 case DM_HOT_ADD:
790 hot_add_req(dm, (struct dm_hot_add *)recv_buffer);
791 break;
792 default:
793 break;
794 }
795
796 if (!time_in_range(jiffies, scan_start, scan_start + HZ))
797 post_status(dm);
798
799 } 795 }
800 796
801 return 0; 797 return 0;
@@ -869,6 +865,8 @@ static void balloon_onchannelcallback(void *context)
869 struct dm_header *dm_hdr; 865 struct dm_header *dm_hdr;
870 struct hv_dynmem_device *dm = hv_get_drvdata(dev); 866 struct hv_dynmem_device *dm = hv_get_drvdata(dev);
871 struct dm_balloon *bal_msg; 867 struct dm_balloon *bal_msg;
868 struct dm_hot_add *ha_msg;
869 union dm_mem_page_range *ha_pg_range;
872 870
873 memset(recv_buffer, 0, sizeof(recv_buffer)); 871 memset(recv_buffer, 0, sizeof(recv_buffer));
874 vmbus_recvpacket(dev->channel, recv_buffer, 872 vmbus_recvpacket(dev->channel, recv_buffer,
@@ -905,8 +903,13 @@ static void balloon_onchannelcallback(void *context)
905 break; 903 break;
906 904
907 case DM_MEM_HOT_ADD_REQUEST: 905 case DM_MEM_HOT_ADD_REQUEST:
906 if (dm->state == DM_HOT_ADD)
907 pr_warn("Currently hot-adding\n");
908 dm->state = DM_HOT_ADD; 908 dm->state = DM_HOT_ADD;
909 complete(&dm->config_event); 909 ha_msg = (struct dm_hot_add *)recv_buffer;
910 ha_pg_range = &ha_msg->range;
911 dm_device.ha_wrk.ha_page_range = *ha_pg_range;
912 schedule_work(&dm_device.ha_wrk.wrk);
910 break; 913 break;
911 914
912 case DM_INFO_MESSAGE: 915 case DM_INFO_MESSAGE:
@@ -950,6 +953,7 @@ static int balloon_probe(struct hv_device *dev,
950 init_completion(&dm_device.host_event); 953 init_completion(&dm_device.host_event);
951 init_completion(&dm_device.config_event); 954 init_completion(&dm_device.config_event);
952 INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up); 955 INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up);
956 INIT_WORK(&dm_device.ha_wrk.wrk, hot_add_req);
953 957
954 dm_device.thread = 958 dm_device.thread =
955 kthread_run(dm_thread_func, &dm_device, "hv_balloon"); 959 kthread_run(dm_thread_func, &dm_device, "hv_balloon");
@@ -1062,6 +1066,7 @@ static int balloon_remove(struct hv_device *dev)
1062 pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned); 1066 pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned);
1063 1067
1064 cancel_work_sync(&dm->balloon_wrk.wrk); 1068 cancel_work_sync(&dm->balloon_wrk.wrk);
1069 cancel_work_sync(&dm->ha_wrk.wrk);
1065 vmbus_close(dev->channel); 1070 vmbus_close(dev->channel);
1066 kthread_stop(dm->thread); 1071 kthread_stop(dm->thread);
1067 kfree(send_buffer); 1072 kfree(send_buffer);