Search Linux Wireless

[PATCH v2 25/50] wilc1000: replace txq_spinlock with ack_filter_lock mutex

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

 



The only purpose left for txq_spinlock is to protect the ack_filter.
The ack_filter is only updated by the tx queue writers and the tx
queue consumer, so interrupts don't have to be disabled and sleeping
is OK.  In other words, we can use a mutex instead of a spinlock.

Signed-off-by: David Mosberger-Tang <davidm@xxxxxxxxxx>
---
 drivers/net/wireless/microchip/wilc1000/cfg80211.c |  1 -
 drivers/net/wireless/microchip/wilc1000/netdev.c   |  2 ++
 drivers/net/wireless/microchip/wilc1000/netdev.h   |  5 ++---
 drivers/net/wireless/microchip/wilc1000/wlan.c     | 12 ++++--------
 4 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
index 0fcc064254f1e..6f19dee813f2a 100644
--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
@@ -1670,7 +1670,6 @@ static void wlan_init_locks(struct wilc *wl)
 	mutex_init(&wl->vif_mutex);
 	mutex_init(&wl->deinit_lock);
 
-	spin_lock_init(&wl->txq_spinlock);
 	mutex_init(&wl->txq_add_to_head_cs);
 	mutex_init(&wl->tx_q_limit_lock);
 
diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c
index 999933532c2de..71cb15f042cdd 100644
--- a/drivers/net/wireless/microchip/wilc1000/netdev.c
+++ b/drivers/net/wireless/microchip/wilc1000/netdev.c
@@ -863,6 +863,7 @@ void wilc_netdev_cleanup(struct wilc *wilc)
 
 	srcu_idx = srcu_read_lock(&wilc->srcu);
 	list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+		mutex_destroy(&vif->ack_filter_lock);
 		if (vif->ndev)
 			unregister_netdev(vif->ndev);
 	}
@@ -929,6 +930,7 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
 	vif->wilc = wl;
 	vif->ndev = ndev;
 	ndev->ml_priv = vif;
+	mutex_init(&vif->ack_filter_lock);
 
 	ndev->netdev_ops = &wilc_netdev_ops;
 
diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.h b/drivers/net/wireless/microchip/wilc1000/netdev.h
index e247f92a409e0..82f38a0e20214 100644
--- a/drivers/net/wireless/microchip/wilc1000/netdev.h
+++ b/drivers/net/wireless/microchip/wilc1000/netdev.h
@@ -190,6 +190,8 @@ struct wilc_vif {
 	struct timer_list during_ip_timer;
 	struct timer_list periodic_rssi;
 	struct rf_info periodic_stat;
+	/* protect ack_filter */
+	struct mutex ack_filter_lock;
 	struct tcp_ack_filter ack_filter;
 	bool connecting;
 	struct wilc_priv priv;
@@ -226,9 +228,6 @@ struct wilc {
 	/* protect head of transmit queue */
 	struct mutex txq_add_to_head_cs;
 
-	/* protect txq_entry_t transmit queue */
-	spinlock_t txq_spinlock;
-
 	/* protect rxq_entry_t receiver queue */
 	struct mutex rxq_cs;
 
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c
index 9b6605e9df296..81180b2f9f4e1 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.c
@@ -124,15 +124,13 @@ static inline void tcp_process(struct net_device *dev, struct sk_buff *tqe)
 	void *buffer = tqe->data;
 	const struct ethhdr *eth_hdr_ptr = buffer;
 	int i;
-	unsigned long flags;
 	struct wilc_vif *vif = netdev_priv(dev);
-	struct wilc *wilc = vif->wilc;
 	struct tcp_ack_filter *f = &vif->ack_filter;
 	const struct iphdr *ip_hdr_ptr;
 	const struct tcphdr *tcp_hdr_ptr;
 	u32 ihl, total_length, data_offset;
 
-	spin_lock_irqsave(&wilc->txq_spinlock, flags);
+	mutex_lock(&vif->ack_filter_lock);
 
 	if (eth_hdr_ptr->h_proto != htons(ETH_P_IP))
 		goto out;
@@ -168,7 +166,7 @@ static inline void tcp_process(struct net_device *dev, struct sk_buff *tqe)
 	}
 
 out:
-	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+	mutex_unlock(&vif->ack_filter_lock);
 }
 
 static void wilc_wlan_tx_packet_done(struct sk_buff *tqe, int status)
@@ -201,12 +199,10 @@ static void wilc_wlan_txq_drop_net_pkt(struct sk_buff *tqe)
 static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
 {
 	struct wilc_vif *vif = netdev_priv(dev);
-	struct wilc *wilc = vif->wilc;
 	struct tcp_ack_filter *f = &vif->ack_filter;
 	u32 i = 0;
-	unsigned long flags;
 
-	spin_lock_irqsave(&wilc->txq_spinlock, flags);
+	mutex_lock(&vif->ack_filter_lock);
 	for (i = f->pending_base;
 	     i < (f->pending_base + f->pending_acks_idx); i++) {
 		u32 index;
@@ -238,7 +234,7 @@ static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
 	else
 		f->pending_base = 0;
 
-	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
+	mutex_unlock(&vif->ack_filter_lock);
 }
 
 void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value)
-- 
2.25.1




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

  Powered by Linux