diff mbox

mac80211: Fix power save state stuck in ACTIVE caused by race between suspend and Tx packet.

Message ID 1433067731-20114-1-git-send-email-chaitanya.mgit@gmail.com (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show

Commit Message

Krishna Chaitanya May 31, 2015, 10:22 a.m. UTC
From: Chaitanya T K <chaitanya.mgit@gmail.com>

If we receive suspend after TX path has executed
dynamic ps disable work, the driver will be in 
ACTIVE state during suspend and even after it 
resumes. 

As before suspend all data packets are flushed
it is safe to put the driver in to sleep for
optimal power during suspend or up on resume.

Signed-off-by: Chaitanya T K <chaitanya.mgit@gmail.com>
---
 net/mac80211/pm.c |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Krishna Chaitanya May 31, 2015, 10:23 a.m. UTC | #1
On Sun, May 31, 2015 at 3:52 PM, Chaitanya T K <chaitanya.mgit@gmail.com> wrote:
> From: Chaitanya T K <chaitanya.mgit@gmail.com>
>
> If we receive suspend after TX path has executed
> dynamic ps disable work, the driver will be in
> ACTIVE state during suspend and even after it
> resumes.
>
> As before suspend all data packets are flushed
> it is safe to put the driver in to sleep for
> optimal power during suspend or up on resume.
>
> Signed-off-by: Chaitanya T K <chaitanya.mgit@gmail.com>
> ---
>  net/mac80211/pm.c |   15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
> index ac6ad62..c9d71c2 100644
> --- a/net/mac80211/pm.c
> +++ b/net/mac80211/pm.c
> @@ -76,6 +76,21 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
>                         if (sdata->vif.type != NL80211_IFTYPE_STATION)
>                                 continue;
>                         ieee80211_mgd_quiesce(sdata);
> +                       /* This is to handle a race where suspend
> +                        * is invoked after dynamic ps work disables
> +                        * power save due to TX. This causes the driver
> +                        * to be stuck in ACTIVE during suspend and
> +                        * after resume unless there is another TX,
> +                        * after which the dynamic ps puts driver
> +                        * back to DOZE.
> +                        */
> +                       if (sdata->u.mgd.associated &&
> +                           sdata->u.mgd.powersave &&
> +                            !(local->hw.conf.flags & IEEE80211_CONF_PS)) {
> +                               local->hw.conf.flags |= IEEE80211_CONF_PS;
> +                               ieee80211_hw_config(local,
> +                                                   IEEE80211_CONF_CHANGE_PS);
> +                       }
>                 }
>
>                 err = drv_suspend(local, wowlan);


Johannes,

I was final able to fix my "from" problem in git send-email.
Sorry for previous spamming. We can continue the discussion
in this thread.

Regards,
Chaitanya T K>
Johannes Berg June 1, 2015, 2:45 p.m. UTC | #2
On Sun, 2015-05-31 at 15:52 +0530, Chaitanya T K wrote:
> From: Chaitanya T K <chaitanya.mgit@gmail.com>
> 
> If we receive suspend after TX path has executed
> dynamic ps disable work, the driver will be in 
> ACTIVE state during suspend and even after it 
> resumes. 
> 
> As before suspend all data packets are flushed
> it is safe to put the driver in to sleep for
> optimal power during suspend or up on resume.

Now that I've actually looked into the code, the patch makes some sense.

However, please rewrite the commit log and the comment in the code.

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index ac6ad62..c9d71c2 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -76,6 +76,21 @@  int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
 			if (sdata->vif.type != NL80211_IFTYPE_STATION)
 				continue;
 			ieee80211_mgd_quiesce(sdata);
+			/* This is to handle a race where suspend
+			 * is invoked after dynamic ps work disables
+			 * power save due to TX. This causes the driver
+			 * to be stuck in ACTIVE during suspend and
+			 * after resume unless there is another TX,
+			 * after which the dynamic ps puts driver
+			 * back to DOZE.
+			 */
+			if (sdata->u.mgd.associated &&
+			    sdata->u.mgd.powersave &&
+			     !(local->hw.conf.flags & IEEE80211_CONF_PS)) {
+				local->hw.conf.flags |= IEEE80211_CONF_PS;
+				ieee80211_hw_config(local,
+						    IEEE80211_CONF_CHANGE_PS);
+			}
 		}
 
 		err = drv_suspend(local, wowlan);