All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marcel Holtmann <marcel@holtmann.org>
To: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Cc: linux-bluetooth@vger.kernel.org
Subject: Re: [PATCH v2] Bluetooth: hci_sync: Fix not processing all entries on cmd_sync_work
Date: Thu, 3 Mar 2022 13:36:48 +0100	[thread overview]
Message-ID: <4E5B9E16-B6B5-430E-BB26-D6919F448F6E@holtmann.org> (raw)
In-Reply-To: <20220302210245.392267-1-luiz.dentz@gmail.com>

Hi Luiz,

> hci_cmd_sync_queue can be called multiple times, each adding a
> hci_cmd_sync_work_entry, before hci_cmd_sync_work is run so this makes
> sure they are all dequeued properly otherwise it creates a backlog of
> entries that are never run.
> 
> Link: https://lore.kernel.org/all/CAJCQCtSeUtHCgsHXLGrSTWKmyjaQDbDNpP4rb0i+RE+L2FTXSA@mail.gmail.com/T/
> Fixes: 6a98e3836fa20 ("Bluetooth: Add helper for serialized HCI command execution")
> Tested-by: Chris Clayton <chris2553@googlemail.com>
> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> ---
> net/bluetooth/hci_sync.c | 39 +++++++++++++++++++++------------------
> 1 file changed, 21 insertions(+), 18 deletions(-)
> 
> diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
> index d146d4efae43..06c6e954dcbd 100644
> --- a/net/bluetooth/hci_sync.c
> +++ b/net/bluetooth/hci_sync.c
> @@ -283,33 +283,36 @@ static void hci_cmd_sync_work(struct work_struct *work)
> 
> 	bt_dev_dbg(hdev, "");
> 
> -	mutex_lock(&hdev->cmd_sync_work_lock);
> -	entry = list_first_entry(&hdev->cmd_sync_work_list,
> -				 struct hci_cmd_sync_work_entry, list);
> -	if (entry) {
> -		list_del(&entry->list);
> +	/* Dequeue all entries and run them */
> +	while (1) {
> +		mutex_lock(&hdev->cmd_sync_work_lock);
> +		entry = list_first_entry_or_null(&hdev->cmd_sync_work_list,
> +						 struct hci_cmd_sync_work_entry,
> +						 list);
> +		if (entry)
> +			list_del(&entry->list);
> +		mutex_unlock(&hdev->cmd_sync_work_lock);
> +
> +		if (!entry)
> +			break;
> +
> 		func = entry->func;
> 		data = entry->data;
> 		destroy = entry->destroy;
> 		kfree(entry);
> -	} else {
> -		func = NULL;
> -		data = NULL;
> -		destroy = NULL;
> -	}
> -	mutex_unlock(&hdev->cmd_sync_work_lock);
> 
> -	if (func) {
> -		int err;
> +		if (func) {
> +			int err;
> 
> -		hci_req_sync_lock(hdev);
> +			hci_req_sync_lock(hdev);
> 
> -		err = func(hdev, data);
> +			err = func(hdev, data);
> 
> -		if (destroy)
> -			destroy(hdev, data, err);
> +			if (destroy)
> +				destroy(hdev, data, err);
> 
> -		hci_req_sync_unlock(hdev);
> +			hci_req_sync_unlock(hdev);
> +		}
> 	}
> }

I really don’t get this. I already gave you how I think this should look like and you still keep the massive amount of variables for no apparent reason. If I am stupid and made a mistake, then please enlighten me, otherwise this should look like this:

@@ -276,40 +276,37 @@ EXPORT_SYMBOL(__hci_cmd_sync_status);
 static void hci_cmd_sync_work(struct work_struct *work)
 {
        struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_sync_work);
-       struct hci_cmd_sync_work_entry *entry;
-       hci_cmd_sync_work_func_t func;
-       hci_cmd_sync_work_destroy_t destroy;
-       void *data;
 
        bt_dev_dbg(hdev, "");
 
-       mutex_lock(&hdev->cmd_sync_work_lock);
-       entry = list_first_entry(&hdev->cmd_sync_work_list,
-                                struct hci_cmd_sync_work_entry, list);
-       if (entry) {
-               list_del(&entry->list);
-               func = entry->func;
-               data = entry->data;
-               destroy = entry->destroy;
+       /* Dequeue all entries and run them */
+       while (1) {
+               struct hci_cmd_sync_work_entry *entry;
+
+               mutex_lock(&hdev->cmd_sync_work_lock);
+               entry = list_first_entry_or_null(&hdev->cmd_sync_work_list,
+                                                struct hci_cmd_sync_work_entry,
+                                                list);
+               if (entry)
+                       list_del(&entry->list);
+               mutex_unlock(&hdev->cmd_sync_work_lock);
+
+               if (!entry)
+                       break;
+
+               bt_dev_dbg(hdev, "entry %p", entry);
+
+               if (entry->func) {
+                       int err;
+
+                       hci_req_sync_lock(hdev);
+                       err = entry->func(hdev, entry->data);
+                       if (entry->destroy)
+                               entry->destroy(hdev, entry->data, err);
+                       hci_req_sync_unlock(hdev);
+               }
+
                kfree(entry);
-       } else {
-               func = NULL;
-               data = NULL;
-               destroy = NULL;
-       }
-       mutex_unlock(&hdev->cmd_sync_work_lock);
-
-       if (func) {
-               int err;
-
-               hci_req_sync_lock(hdev);
-
-               err = func(hdev, data);
-
-               if (destroy)
-                       destroy(hdev, data, err);
-
-               hci_req_sync_unlock(hdev);
        }
 }

I amended the patch now and applied it to bluetooth-stable tree. I am not doing any more iterations to get this right.

Regards

Marcel


      parent reply	other threads:[~2022-03-03 12:36 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-02 21:02 [PATCH v2] Bluetooth: hci_sync: Fix not processing all entries on cmd_sync_work Luiz Augusto von Dentz
2022-03-02 22:16 ` [v2] " bluez.test.bot
2022-03-03 12:36 ` Marcel Holtmann [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E5B9E16-B6B5-430E-BB26-D6919F448F6E@holtmann.org \
    --to=marcel@holtmann.org \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.