Search Linux Wireless

[PATCH 3/7] ath10k: drain wmi quickly upon hw restart

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Once restart is started it doesn't make much sense
to process pending requests. Just drop all WMI
commands that are in progress.

This speeds up hw restart because conf_mutex can
be held in some cases while a crash happens. In
that case WMI tx credits are no replenished and 3
second timeout for each WMI command happens. This
could add up to quite a lot.

Signed-off-by: Michal Kazior <michal.kazior@xxxxxxxxx>
---
 drivers/net/wireless/ath/ath10k/core.c |  5 +++++
 drivers/net/wireless/ath/ath10k/core.h |  3 +++
 drivers/net/wireless/ath/ath10k/wmi.c  | 12 +++++++++++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index acc22cc..3f4d28f 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -706,6 +706,11 @@ static void ath10k_core_restart_work(struct work_struct *work)
 
 void ath10k_core_restart(struct ath10k *ar)
 {
+	spin_lock_bh(&ar->data_lock);
+	ar->wmi.drop = true;
+	wake_up(&ar->wmi.tx_credits_wq);
+	spin_unlock_bh(&ar->data_lock);
+
 	queue_work(ar->workqueue, &ar->restart_work);
 }
 EXPORT_SYMBOL(ath10k_core_restart);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 170094d..074cb41 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -113,6 +113,9 @@ struct ath10k_wmi {
 
 	u32 num_mem_chunks;
 	struct ath10k_mem_chunk mem_chunks[ATH10K_MAX_MEM_REQS];
+
+	/* protected by ar->data_lock. used to speed up hw restart */
+	bool drop;
 };
 
 struct ath10k_peer_stat {
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 72cc4f2..159d744 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -621,7 +621,13 @@ static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb,
 		/* try to send pending beacons first. they take priority */
 		ath10k_wmi_tx_beacons_nowait(ar);
 
-		ret = ath10k_wmi_cmd_send_nowait(ar, skb, cmd_id);
+		spin_lock_bh(&ar->data_lock);
+		if (ar->wmi.drop)
+			ret = -EPERM;
+		else
+			ret = ath10k_wmi_cmd_send_nowait(ar, skb, cmd_id);
+		spin_unlock_bh(&ar->data_lock);
+
 		(ret != -EAGAIN);
 	}), 3*HZ);
 
@@ -2341,6 +2347,10 @@ int ath10k_wmi_attach(struct ath10k *ar)
 	init_completion(&ar->wmi.unified_ready);
 	init_waitqueue_head(&ar->wmi.tx_credits_wq);
 
+	spin_lock_bh(&ar->data_lock);
+	ar->wmi.drop = false;
+	spin_unlock_bh(&ar->data_lock);
+
 	return 0;
 }
 
-- 
1.8.5.3

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




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux