mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 15:50:59 +07:00
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>
This commit is contained in:
parent
7a64b864a0
commit
6571b2dab4
@ -412,6 +412,11 @@ struct dm_info_msg {
|
|||||||
* End protocol definitions.
|
* End protocol definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct balloon_state {
|
||||||
|
__u32 num_pages;
|
||||||
|
struct work_struct wrk;
|
||||||
|
};
|
||||||
|
|
||||||
static bool hot_add;
|
static bool hot_add;
|
||||||
static bool do_hot_add;
|
static bool do_hot_add;
|
||||||
/*
|
/*
|
||||||
@ -459,7 +464,12 @@ struct hv_dynmem_device {
|
|||||||
unsigned int num_pages_ballooned;
|
unsigned int num_pages_ballooned;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This thread handles both balloon/hot-add
|
* State to manage the ballooning (up) operation.
|
||||||
|
*/
|
||||||
|
struct balloon_state balloon_wrk;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This thread handles hot-add
|
||||||
* requests from the host as well as notifying
|
* requests from the host as well as notifying
|
||||||
* the host with regards to memory pressure in
|
* the host with regards to memory pressure in
|
||||||
* the guest.
|
* the guest.
|
||||||
@ -657,9 +667,9 @@ static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req)
|
static void balloon_up(struct work_struct *dummy)
|
||||||
{
|
{
|
||||||
int num_pages = req->num_pages;
|
int num_pages = dm_device.balloon_wrk.num_pages;
|
||||||
int num_ballooned = 0;
|
int num_ballooned = 0;
|
||||||
struct dm_balloon_response *bl_resp;
|
struct dm_balloon_response *bl_resp;
|
||||||
int alloc_unit;
|
int alloc_unit;
|
||||||
@ -684,14 +694,14 @@ static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req)
|
|||||||
|
|
||||||
|
|
||||||
num_pages -= num_ballooned;
|
num_pages -= num_ballooned;
|
||||||
num_ballooned = alloc_balloon_pages(dm, num_pages,
|
num_ballooned = alloc_balloon_pages(&dm_device, num_pages,
|
||||||
bl_resp, alloc_unit,
|
bl_resp, alloc_unit,
|
||||||
&alloc_error);
|
&alloc_error);
|
||||||
|
|
||||||
if ((alloc_error) || (num_ballooned == num_pages)) {
|
if ((alloc_error) || (num_ballooned == num_pages)) {
|
||||||
bl_resp->more_pages = 0;
|
bl_resp->more_pages = 0;
|
||||||
done = true;
|
done = true;
|
||||||
dm->state = DM_INITIALIZED;
|
dm_device.state = DM_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -719,7 +729,7 @@ static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req)
|
|||||||
pr_info("Balloon response failed\n");
|
pr_info("Balloon response failed\n");
|
||||||
|
|
||||||
for (i = 0; i < bl_resp->range_count; i++)
|
for (i = 0; i < bl_resp->range_count; i++)
|
||||||
free_balloon_pages(dm,
|
free_balloon_pages(&dm_device,
|
||||||
&bl_resp->range_array[i]);
|
&bl_resp->range_array[i]);
|
||||||
|
|
||||||
done = true;
|
done = true;
|
||||||
@ -775,9 +785,6 @@ static int dm_thread_func(void *dm_dev)
|
|||||||
|
|
||||||
scan_start = jiffies;
|
scan_start = jiffies;
|
||||||
switch (dm->state) {
|
switch (dm->state) {
|
||||||
case DM_BALLOON_UP:
|
|
||||||
balloon_up(dm, (struct dm_balloon *)recv_buffer);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DM_HOT_ADD:
|
case DM_HOT_ADD:
|
||||||
hot_add_req(dm, (struct dm_hot_add *)recv_buffer);
|
hot_add_req(dm, (struct dm_hot_add *)recv_buffer);
|
||||||
@ -861,6 +868,7 @@ static void balloon_onchannelcallback(void *context)
|
|||||||
struct dm_message *dm_msg;
|
struct dm_message *dm_msg;
|
||||||
struct dm_header *dm_hdr;
|
struct dm_header *dm_hdr;
|
||||||
struct hv_dynmem_device *dm = hv_get_drvdata(dev);
|
struct hv_dynmem_device *dm = hv_get_drvdata(dev);
|
||||||
|
struct dm_balloon *bal_msg;
|
||||||
|
|
||||||
memset(recv_buffer, 0, sizeof(recv_buffer));
|
memset(recv_buffer, 0, sizeof(recv_buffer));
|
||||||
vmbus_recvpacket(dev->channel, recv_buffer,
|
vmbus_recvpacket(dev->channel, recv_buffer,
|
||||||
@ -882,8 +890,12 @@ static void balloon_onchannelcallback(void *context)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DM_BALLOON_REQUEST:
|
case DM_BALLOON_REQUEST:
|
||||||
|
if (dm->state == DM_BALLOON_UP)
|
||||||
|
pr_warn("Currently ballooning\n");
|
||||||
|
bal_msg = (struct dm_balloon *)recv_buffer;
|
||||||
dm->state = DM_BALLOON_UP;
|
dm->state = DM_BALLOON_UP;
|
||||||
complete(&dm->config_event);
|
dm_device.balloon_wrk.num_pages = bal_msg->num_pages;
|
||||||
|
schedule_work(&dm_device.balloon_wrk.wrk);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DM_UNBALLOON_REQUEST:
|
case DM_UNBALLOON_REQUEST:
|
||||||
@ -937,6 +949,7 @@ static int balloon_probe(struct hv_device *dev,
|
|||||||
dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7;
|
dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7;
|
||||||
init_completion(&dm_device.host_event);
|
init_completion(&dm_device.host_event);
|
||||||
init_completion(&dm_device.config_event);
|
init_completion(&dm_device.config_event);
|
||||||
|
INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up);
|
||||||
|
|
||||||
dm_device.thread =
|
dm_device.thread =
|
||||||
kthread_run(dm_thread_func, &dm_device, "hv_balloon");
|
kthread_run(dm_thread_func, &dm_device, "hv_balloon");
|
||||||
@ -1048,6 +1061,7 @@ static int balloon_remove(struct hv_device *dev)
|
|||||||
if (dm->num_pages_ballooned != 0)
|
if (dm->num_pages_ballooned != 0)
|
||||||
pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned);
|
pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned);
|
||||||
|
|
||||||
|
cancel_work_sync(&dm->balloon_wrk.wrk);
|
||||||
vmbus_close(dev->channel);
|
vmbus_close(dev->channel);
|
||||||
kthread_stop(dm->thread);
|
kthread_stop(dm->thread);
|
||||||
kfree(send_buffer);
|
kfree(send_buffer);
|
||||||
|
Loading…
Reference in New Issue
Block a user