From: Marcel Holtmann <marcel@holtmann.org>
To: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>,
Alain Michaud <alainm@chromium.org>,
linux-bluetooth@vger.kernel.org,
chromeos-bluetooth-upstreaming@chromium.org,
"David S. Miller" <davem@davemloft.net>,
Johan Hedberg <johan.hedberg@gmail.com>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Jakub Kicinski <kuba@kernel.org>
Subject: Re: [RFC PATCH v4 5/5] Bluetooth: Pause discovery and advertising during suspend
Date: Sun, 8 Mar 2020 09:38:59 +0100 [thread overview]
Message-ID: <DB7CF910-5065-45A4-BD4E-A2FDA5B56E67@holtmann.org> (raw)
In-Reply-To: <20200303170610.RFC.v4.5.Iccdad520469ca3524a7e5966c5f88e5bca756e13@changeid>
Hi Abhishek,
> To prevent spurious wake ups, we disable any discovery or advertising
> when we enter suspend and restore it when we exit suspend. While paused,
> we disable any management requests to modify discovery or advertising.
>
> Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
> ---
>
> Changes in v4: None
> Changes in v3: None
> Changes in v2:
> * Refactored pause discovery + advertising into its own patch
>
> include/net/bluetooth/hci_core.h | 11 ++++++++
> net/bluetooth/hci_request.c | 43 ++++++++++++++++++++++++++++++++
> net/bluetooth/mgmt.c | 41 ++++++++++++++++++++++++++++++
> 3 files changed, 95 insertions(+)
>
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 4eb5b2786048..af264a247636 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -91,6 +91,12 @@ struct discovery_state {
> #define SUSPEND_NOTIFIER_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
>
> enum suspend_tasks {
> + SUSPEND_PAUSE_DISCOVERY,
> + SUSPEND_UNPAUSE_DISCOVERY,
> +
> + SUSPEND_PAUSE_ADVERTISING,
> + SUSPEND_UNPAUSE_ADVERTISING,
> +
> SUSPEND_SCAN_DISABLE,
> SUSPEND_SCAN_ENABLE,
> SUSPEND_DISCONNECTING,
> @@ -409,6 +415,11 @@ struct hci_dev {
>
> struct discovery_state discovery;
>
> + int discovery_old_state;
> + bool discovery_paused;
> + int advertising_old_state;
> + bool advertising_paused;
> +
> struct notifier_block suspend_notifier;
> struct work_struct suspend_prepare;
> enum suspended_state suspend_state_next;
> diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
> index 88fd95d70f89..e25cfb6fd9aa 100644
> --- a/net/bluetooth/hci_request.c
> +++ b/net/bluetooth/hci_request.c
> @@ -1036,6 +1036,28 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
> /* Mark device as suspended */
> hdev->suspended = true;
>
> + /* Pause discovery if not already stopped */
> + old_state = hdev->discovery.state;
> + if (old_state != DISCOVERY_STOPPED) {
> + set_bit(SUSPEND_PAUSE_DISCOVERY, hdev->suspend_tasks);
> + hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
> + queue_work(hdev->req_workqueue, &hdev->discov_update);
> + }
> +
> + hdev->discovery_paused = true;
> + hdev->discovery_old_state = old_state;
> +
> + /* Stop advertising */
> + old_state = hci_dev_test_flag(hdev, HCI_ADVERTISING);
> + if (old_state) {
> + set_bit(SUSPEND_PAUSE_ADVERTISING, hdev->suspend_tasks);
> + cancel_delayed_work(&hdev->discov_off);
> + queue_delayed_work(hdev->req_workqueue,
> + &hdev->discov_off, 0);
> + }
> +
> + hdev->advertising_paused = true;
> + hdev->advertising_old_state = old_state;
> /* Disable page scan */
> page_scan = SCAN_DISABLED;
> hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &page_scan);
> @@ -1081,6 +1103,27 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
> hci_req_clear_event_filter(&req);
> /* Reset passive/background scanning to normal */
> hci_req_config_le_suspend_scan(&req);
> +
> + /* Unpause advertising */
> + hdev->advertising_paused = false;
> + if (hdev->advertising_old_state) {
> + set_bit(SUSPEND_UNPAUSE_ADVERTISING,
> + hdev->suspend_tasks);
> + hci_dev_set_flag(hdev, HCI_ADVERTISING);
> + queue_work(hdev->req_workqueue,
> + &hdev->discoverable_update);
> + hdev->advertising_old_state = 0;
> + }
> +
> + /* Unpause discovery */
> + hdev->discovery_paused = false;
> + if (hdev->discovery_old_state != DISCOVERY_STOPPED &&
> + hdev->discovery_old_state != DISCOVERY_STOPPING) {
> + set_bit(SUSPEND_UNPAUSE_DISCOVERY, hdev->suspend_tasks);
> + hci_discovery_set_state(hdev, DISCOVERY_STARTING);
> + queue_work(hdev->req_workqueue, &hdev->discov_update);
> + }
> +
> hci_req_run(&req, suspend_req_complete);
> }
>
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index f6751ce0d561..28572579c06d 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -1387,6 +1387,12 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
> goto failed;
> }
>
> + if (hdev->advertising_paused) {
> + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
> + MGMT_STATUS_BUSY);
> + goto failed;
> + }
> +
> if (!hdev_is_powered(hdev)) {
> bool changed = false;
>
> @@ -3870,6 +3876,13 @@ void mgmt_start_discovery_complete(struct hci_dev *hdev, u8 status)
> }
>
> hci_dev_unlock(hdev);
> +
> + /* Handle suspend notifier */
> + if (test_and_clear_bit(SUSPEND_UNPAUSE_DISCOVERY,
> + hdev->suspend_tasks)) {
> + BT_DBG("Unpaused discovery");
> + wake_up(&hdev->suspend_wait_q);
> + }
> }
>
> static bool discovery_type_is_valid(struct hci_dev *hdev, uint8_t type,
> @@ -3931,6 +3944,13 @@ static int start_discovery_internal(struct sock *sk, struct hci_dev *hdev,
> goto failed;
> }
>
> + /* Can't start discovery when it is paused */
> + if (hdev->discovery_paused) {
> + err = mgmt_cmd_complete(sk, hdev->id, op, MGMT_STATUS_BUSY,
> + &cp->type, sizeof(cp->type));
> + goto failed;
> + }
> +
> /* Clear the discovery filter first to free any previously
> * allocated memory for the UUID list.
> */
> @@ -4098,6 +4118,12 @@ void mgmt_stop_discovery_complete(struct hci_dev *hdev, u8 status)
> }
>
> hci_dev_unlock(hdev);
> +
> + /* Handle suspend notifier */
> + if (test_and_clear_bit(SUSPEND_PAUSE_DISCOVERY, hdev->suspend_tasks)) {
> + BT_DBG("Paused discovery");
> + wake_up(&hdev->suspend_wait_q);
> + }
> }
>
> static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
> @@ -4329,6 +4355,17 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status,
> if (match.sk)
> sock_put(match.sk);
>
> + /* Handle suspend notifier */
> + if (test_and_clear_bit(SUSPEND_PAUSE_ADVERTISING,
> + hdev->suspend_tasks)) {
> + BT_DBG("Paused advertising");
> + wake_up(&hdev->suspend_wait_q);
> + } else if (test_and_clear_bit(SUSPEND_UNPAUSE_ADVERTISING,
> + hdev->suspend_tasks)) {
> + BT_DBG("Unpaused advertising");
> + wake_up(&hdev->suspend_wait_q);
> + }
> +
> /* If "Set Advertising" was just disabled and instance advertising was
> * set up earlier, then re-enable multi-instance advertising.
> */
> @@ -4380,6 +4417,10 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
> return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
> MGMT_STATUS_INVALID_PARAMS);
>
> + if (hdev->advertising_paused)
> + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
> + MGMT_STATUS_BUSY);
> +
> hci_dev_lock(hdev);
>
> val = !!cp->val;
looks good. Just make this 4/5 and use bt_dev_dbg where possible.
Regards
Marcel
prev parent reply other threads:[~2020-03-08 8:39 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-04 1:06 [RFC PATCH v4 0/5] Bluetooth: Handle system suspend gracefully Abhishek Pandit-Subedi
2020-03-04 1:06 ` [RFC PATCH v4 1/5] Bluetooth: Add mgmt op set_wake_capable Abhishek Pandit-Subedi
2020-03-08 8:28 ` Marcel Holtmann
2020-03-04 1:06 ` [RFC PATCH v4 2/5] Bluetooth: Handle PM_SUSPEND_PREPARE and PM_POST_SUSPEND Abhishek Pandit-Subedi
2020-03-08 8:28 ` Marcel Holtmann
2020-03-04 1:06 ` [RFC PATCH v4 3/5] Bluetooth: Handle BR/EDR devices during suspend Abhishek Pandit-Subedi
2020-03-08 8:30 ` Marcel Holtmann
2020-03-04 1:06 ` [RFC PATCH v4 4/5] Bluetooth: Handle LE " Abhishek Pandit-Subedi
2020-03-08 8:37 ` Marcel Holtmann
2020-03-04 1:06 ` [RFC PATCH v4 5/5] Bluetooth: Pause discovery and advertising " Abhishek Pandit-Subedi
2020-03-08 8:38 ` 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=DB7CF910-5065-45A4-BD4E-A2FDA5B56E67@holtmann.org \
--to=marcel@holtmann.org \
--cc=abhishekpandit@chromium.org \
--cc=alainm@chromium.org \
--cc=chromeos-bluetooth-upstreaming@chromium.org \
--cc=davem@davemloft.net \
--cc=johan.hedberg@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-bluetooth@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luiz.dentz@gmail.com \
--cc=netdev@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).