lkml.org 
[lkml]   [2022]   [Mar]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [PATCH] virt: acrn: fix invalid check past list iterator
On Sat, Mar 19, 2022 at 09:38:19PM +0100, Jakob Koschel wrote:
> The condition retry == 0 is theoretically possible even if 'client'
> does not point to a valid element because no break was hit.
>
> To only execute the dev_warn if actually a break within the loop was
> hit, a separate variable is used that is only set if it is ensured to
> point to a valid client struct.
>
Hi Koschel

Thanks for you to help us to try to improve the code. Maybe you don't get the point.
The dev_warn should only been called when has_pending = true && retry == 0

If retry > 0 and has_pending is true, we would call schedule_timeout_interruptible
to schedule out to wait all the pending I/O requests would been completed.

Thanks.

> Signed-off-by: Jakob Koschel <jakobkoschel@gmail.com>
> ---
> drivers/virt/acrn/ioreq.c | 13 ++++++++-----
> 1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/virt/acrn/ioreq.c b/drivers/virt/acrn/ioreq.c
> index 5ff1c53740c0..bdf7cedce926 100644
> --- a/drivers/virt/acrn/ioreq.c
> +++ b/drivers/virt/acrn/ioreq.c
> @@ -211,7 +211,7 @@ static int ioreq_task(void *data)
> */
> void acrn_ioreq_request_clear(struct acrn_vm *vm)
> {
> - struct acrn_ioreq_client *client;
> + struct acrn_ioreq_client *client, *iter;
> bool has_pending = false;
> unsigned long vcpu;
> int retry = 10;
> @@ -228,17 +228,20 @@ void acrn_ioreq_request_clear(struct acrn_vm *vm)
> */
> do {
> spin_lock_bh(&vm->ioreq_clients_lock);
> - list_for_each_entry(client, &vm->ioreq_clients, list) {
> - has_pending = has_pending_request(client);
> - if (has_pending)
> + client = NULL;
> + list_for_each_entry(iter, &vm->ioreq_clients, list) {
> + has_pending = has_pending_request(iter);
> + if (has_pending) {
> + client = iter;
> break;
> + }
> }
> spin_unlock_bh(&vm->ioreq_clients_lock);
>
> if (has_pending)
> schedule_timeout_interruptible(HZ / 100);
> } while (has_pending && --retry > 0);
> - if (retry == 0)
> + if (client)
> dev_warn(acrn_dev.this_device,
> "%s cannot flush pending request!\n", client->name);
>
>
> base-commit: 34e047aa16c0123bbae8e2f6df33e5ecc1f56601
> --
> 2.25.1
>

\
 
 \ /
  Last update: 2022-03-30 09:57    [W:0.128 / U:0.704 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site