| From 319933a80fd4f07122466a77f93e5019d71be74c Mon Sep 17 00:00:00 2001 |
| From: Juergen Gross <jgross@suse.com> |
| Date: Tue, 5 Oct 2021 15:34:33 +0200 |
| Subject: xen/balloon: fix cancelled balloon action |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Juergen Gross <jgross@suse.com> |
| |
| commit 319933a80fd4f07122466a77f93e5019d71be74c upstream. |
| |
| In case a ballooning action is cancelled the new kernel thread handling |
| the ballooning might end up in a busy loop. |
| |
| Fix that by handling the cancelled action gracefully. |
| |
| While at it introduce a short wait for the BP_WAIT case. |
| |
| Cc: stable@vger.kernel.org |
| Fixes: 8480ed9c2bbd56 ("xen/balloon: use a kernel thread instead a workqueue") |
| Reported-by: Marek Marczykowski-Gรณrecki <marmarek@invisiblethingslab.com> |
| Signed-off-by: Juergen Gross <jgross@suse.com> |
| Tested-by: Jason Andryuk <jandryuk@gmail.com> |
| Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> |
| Link: https://lore.kernel.org/r/20211005133433.32008-1-jgross@suse.com |
| Signed-off-by: Juergen Gross <jgross@suse.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/xen/balloon.c | 21 +++++++++++++++------ |
| 1 file changed, 15 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/xen/balloon.c |
| +++ b/drivers/xen/balloon.c |
| @@ -508,12 +508,12 @@ static enum bp_state decrease_reservatio |
| } |
| |
| /* |
| - * Stop waiting if either state is not BP_EAGAIN and ballooning action is |
| - * needed, or if the credit has changed while state is BP_EAGAIN. |
| + * Stop waiting if either state is BP_DONE and ballooning action is |
| + * needed, or if the credit has changed while state is not BP_DONE. |
| */ |
| static bool balloon_thread_cond(enum bp_state state, long credit) |
| { |
| - if (state != BP_EAGAIN) |
| + if (state == BP_DONE) |
| credit = 0; |
| |
| return current_credit() != credit || kthread_should_stop(); |
| @@ -533,10 +533,19 @@ static int balloon_thread(void *unused) |
| |
| set_freezable(); |
| for (;;) { |
| - if (state == BP_EAGAIN) |
| - timeout = balloon_stats.schedule_delay * HZ; |
| - else |
| + switch (state) { |
| + case BP_DONE: |
| + case BP_ECANCELED: |
| timeout = 3600 * HZ; |
| + break; |
| + case BP_EAGAIN: |
| + timeout = balloon_stats.schedule_delay * HZ; |
| + break; |
| + case BP_WAIT: |
| + timeout = HZ; |
| + break; |
| + } |
| + |
| credit = current_credit(); |
| |
| wait_event_freezable_timeout(balloon_thread_wq, |