diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2013-03-15 15:25:41 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-15 15:11:50 -0400 |
commit | c51af826cf062af3c49a99a05a33236d93c57e72 (patch) | |
tree | f1f61f8e04b17a16820d61a311059cc6a6efaec6 /drivers/hv | |
parent | 6571b2dab4eb6c7061160490db984dbc01e5626d (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.c | 41 |
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 | ||
420 | struct hot_add_wrk { | ||
421 | union dm_mem_page_range ha_page_range; | ||
422 | struct work_struct wrk; | ||
423 | }; | ||
424 | |||
420 | static bool hot_add; | 425 | static bool hot_add; |
421 | static bool do_hot_add; | 426 | static 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 | ||
487 | static struct hv_dynmem_device dm_device; | 497 | static struct hv_dynmem_device dm_device; |
488 | 498 | ||
489 | static void hot_add_req(struct hv_dynmem_device *dm, struct dm_hot_add *msg) | 499 | static 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); |