* [PATCH] mt76: fix endianness sparse warnings
From: Ryder Lee @ 2019-04-25 14:42 UTC (permalink / raw)
To: Lorenzo Bianconi, Felix Fietkau
Cc: Roy Luo, Sean Wang, linux-wireless, linux-mediatek, linux-kernel,
Ryder Lee
Fix many warnings with incorrect endian assumptions.
Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 2f2961ee0a92..af5769d05e6f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -627,7 +627,7 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
status->aggr = unicast &&
!ieee80211_is_qos_nullfunc(hdr->frame_control);
status->tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
- status->seqno = IEEE80211_SEQ_TO_SN(hdr->seq_ctrl);
+ status->seqno = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));
return 0;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index 1bf3e7b5f6a7..4b934b0f5a39 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -235,7 +235,7 @@ int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
status->aggr = unicast &&
!ieee80211_is_qos_nullfunc(hdr->frame_control);
status->tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
- status->seqno = IEEE80211_SEQ_TO_SN(hdr->seq_ctrl);
+ status->seqno = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));
return 0;
}
@@ -337,7 +337,7 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
struct ieee80211_vif *vif = info->control.vif;
int tx_count = 8;
u8 fc_type, fc_stype, p_fmt, q_idx, omac_idx = 0;
- u16 fc = le16_to_cpu(hdr->frame_control);
+ __le16 fc = hdr->frame_control;
u16 seqno = 0;
u32 val;
@@ -353,8 +353,8 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
tx_count = msta->rate_count;
}
- fc_type = (fc & IEEE80211_FCTL_FTYPE) >> 2;
- fc_stype = (fc & IEEE80211_FCTL_STYPE) >> 4;
+ fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2;
+ fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4;
if (ieee80211_is_data(fc)) {
q_idx = skb_get_queue_mapping(skb);
@@ -468,7 +468,7 @@ void mt7615_txp_skb_unmap(struct mt76_dev *dev,
txp = (struct mt7615_txp *)(txwi + MT_TXD_SIZE);
for (i = 1; i < txp->nbuf; i++)
dma_unmap_single(dev->dev, le32_to_cpu(txp->buf[i]),
- le32_to_cpu(txp->len[i]), DMA_TO_DEVICE);
+ le16_to_cpu(txp->len[i]), DMA_TO_DEVICE);
}
int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
@@ -506,7 +506,7 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
txp = (struct mt7615_txp *)(txwi + MT_TXD_SIZE);
for (i = 0; i < nbuf; i++) {
txp->buf[i] = cpu_to_le32(tx_info->buf[i + 1].addr);
- txp->len[i] = cpu_to_le32(tx_info->buf[i + 1].len);
+ txp->len[i] = cpu_to_le16(tx_info->buf[i + 1].len);
}
txp->nbuf = nbuf;
--
2.18.0
^ permalink raw reply related
* RE: [PATCH v8 13/15] x86/split_lock: Enable split lock detection by default
From: Thomas Gleixner @ 2019-04-25 13:04 UTC (permalink / raw)
To: David Laight
Cc: 'Fenghua Yu', Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li, Christopherson Sean J, Kalle Valo,
Michael Chan, linux-kernel, x86, kvm@vger.kernel.org,
netdev@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <551673e41ac649689243cbe060364b0d@AcuMS.aculab.com>
On Thu, 25 Apr 2019, David Laight wrote:
> From: Thomas Gleixne]
> > Sent: 25 April 2019 11:59
> > On Thu, 25 Apr 2019, David Laight wrote:
> >
> > > From: Fenghua Yu
> > > > Sent: 24 April 2019 20:33
> > > > A split locked access locks bus and degrades overall memory access
> > > > performance. When split lock detection feature is enumerated, enable
> > > > the feature by default by writing 1 to bit 29 in MSR TEST_CTL to find
> > > > any split lock issue.
> > >
> > > You can't enable this by default until ALL the known potentially
> > > misaligned locked memory operations have been fixed.
> >
> > Errm? The result will be a WARN_ON() printed and no further damage.
>
> ISTR something about sending SIGSEGV to userspace.
Nope. If the #AC originates from kernel then a warning is printed and the
detection is disabled.
Userspace is a different story. We cannot audit all user space upfront,
right?
> > It's not making anything worse than it is now. In fact we just should add a
> >
> > WARN_ON_ONCE(!aligned_to_long(p)) to all the xxx_bit() operations.
> >
> > so we catch them even when they do not trigger that #AC thingy.
>
> That will explode the kernel code size.
So what? We have enough debug options which make the kernel big. One more
does not really matter.
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH v2 0/3] mt76: suspend/stop/removal fixes
From: Felix Fietkau @ 2019-04-25 12:37 UTC (permalink / raw)
To: Stanislaw Gruszka, linux-wireless; +Cc: Lorenzo Bianconi
In-Reply-To: <20190423103709.7272-1-sgruszka@redhat.com>
On 2019-04-23 12:37, Stanislaw Gruszka wrote:
> Fixes for some coroner cases during suspend/stop/removal intended to
> -next since problems are not reproducible in practice and changes
> relay on -next patches.
Patch 2 and 3 don't apply anymore. Please rebase and resend.
Thanks,
- Felix
^ permalink raw reply
* Re: [PATCH v8 13/15] x86/split_lock: Enable split lock detection by default
From: Peter Zijlstra @ 2019-04-25 11:41 UTC (permalink / raw)
To: David Laight
Cc: 'Thomas Gleixner', 'Fenghua Yu', Ingo Molnar,
Borislav Petkov, H Peter Anvin, Paolo Bonzini, Dave Hansen,
Ashok Raj, Ravi V Shankar, Xiaoyao Li, Christopherson Sean J,
Kalle Valo, Michael Chan, linux-kernel, x86, kvm@vger.kernel.org,
netdev@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <551673e41ac649689243cbe060364b0d@AcuMS.aculab.com>
On Thu, Apr 25, 2019 at 11:13:23AM +0000, David Laight wrote:
> I'm not at all sure that 'compare and exchange' operations
> are atomic on all cpus if the data is misaligned and crosses
> a page boundary and either (or both) pages need faulting in
> (or hit a TLB miss).
Most sane architectures already trap if you attempt that.
^ permalink raw reply
* Re: [PATCH] brcmfmac: allocate msgbuf pktid from 1 to pktids array size
From: Arend Van Spriel @ 2019-04-25 11:22 UTC (permalink / raw)
To: Wright Feng, franky.lin@broadcom.com, hante.meuleman@broadcom.com,
kvalo@codeaurora.org, Chi-Hsien Lin
Cc: linux-wireless@vger.kernel.org,
brcm80211-dev-list.pdl@broadcom.com
In-Reply-To: <1556179487-147593-1-git-send-email-wright.feng@cypress.com>
On 4/25/2019 10:04 AM, Wright Feng wrote:
> Some PCIE firmwares drop txstatus if pktid is 0 and make packet held in
> host side and not be released. If that packet type is 802.1x, the
> pend_8021x_cnt value will be always greater than 0 and show "Timed out
> waiting for no pending 802.1x packets" error message when sending key to
> dongle.
>
> To be compatible with all firmwares, host should allocate msgbuf pktid
> from 1 instead of from 0.
looking at it we are wasting entry 0 with this patch. Could we avoid that?
Regards,
Arend
> Signed-off-by: Wright Feng <wright.feng@cypress.com>
> ---
> drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
> index d3780ea..b2fab3c 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
> @@ -348,7 +348,7 @@ brcmf_msgbuf_alloc_pktid(struct device *dev,
> do {
> (*idx)++;
> if (*idx == pktids->array_size)
> - *idx = 0;
> + *idx = 1;
> if (array[*idx].allocated.counter == 0)
> if (atomic_cmpxchg(&array[*idx].allocated, 0, 1) == 0)
> break;
>
^ permalink raw reply
* RE: [PATCH v8 13/15] x86/split_lock: Enable split lock detection by default
From: David Laight @ 2019-04-25 11:13 UTC (permalink / raw)
To: 'Thomas Gleixner'
Cc: 'Fenghua Yu', Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li, Christopherson Sean J, Kalle Valo,
Michael Chan, linux-kernel, x86, kvm@vger.kernel.org,
netdev@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <alpine.DEB.2.21.1904251255590.1960@nanos.tec.linutronix.de>
From: Thomas Gleixne]
> Sent: 25 April 2019 11:59
> On Thu, 25 Apr 2019, David Laight wrote:
>
> > From: Fenghua Yu
> > > Sent: 24 April 2019 20:33
> > > A split locked access locks bus and degrades overall memory access
> > > performance. When split lock detection feature is enumerated, enable
> > > the feature by default by writing 1 to bit 29 in MSR TEST_CTL to find
> > > any split lock issue.
> >
> > You can't enable this by default until ALL the known potentially
> > misaligned locked memory operations have been fixed.
>
> Errm? The result will be a WARN_ON() printed and no further damage.
ISTR something about sending SIGSEGV to userspace.
> It's not making anything worse than it is now. In fact we just should add a
>
> WARN_ON_ONCE(!aligned_to_long(p)) to all the xxx_bit() operations.
>
> so we catch them even when they do not trigger that #AC thingy.
That will explode the kernel code size.
In any case some of the items I found in a quick scan were bss/data
so the alignment will vary from build to build.
I also found some casts on the xxx_bit() functions in generic code.
I didn't look to see how badly wrong they go on BE systems.
While the x86 xxx_bit() functions could easily be changed to do
32bit accesses, the 'misaligned' operations will affect all
architectures - and may have different effects on others.
I'm not at all sure that 'compare and exchange' operations
are atomic on all cpus if the data is misaligned and crosses
a page boundary and either (or both) pages need faulting in
(or hit a TLB miss).
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply
* Re: [PATCH] mwifiex: Make resume actually do something useful again on SDIO cards
From: Kalle Valo @ 2019-04-25 11:05 UTC (permalink / raw)
To: Douglas Anderson
Cc: linux-rockchip, briannorris, mka, ryandcase, heiko,
Douglas Anderson, David S. Miller, Ganapathi Bhat, linux-wireless,
Amitkumar Karwar, linux-kernel, Nishant Sarmukadam, netdev,
Xinming Hu
In-Reply-To: <20190404040106.40519-1-dianders@chromium.org>
Douglas Anderson <dianders@chromium.org> wrote:
> The commit fc3a2fcaa1ba ("mwifiex: use atomic bitops to represent
> adapter status variables") had a fairly straightforward bug in it. It
> contained this bit of diff:
>
> - if (!adapter->is_suspended) {
> + if (test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {
>
> As you can see the patch missed the "!" when converting to the atomic
> bitops. This meant that the resume hasn't done anything at all since
> that commit landed and suspend/resume for mwifiex SDIO cards has been
> totally broken.
>
> After fixing this mwifiex suspend/resume appears to work again, at
> least with the simple testing I've done.
>
> Fixes: fc3a2fcaa1ba ("mwifiex: use atomic bitops to represent adapter status variables")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> Reviewed-by: Brian Norris <briannorris@chromium.org>
Patch applied to wireless-drivers.git, thanks.
b82d6c1f8f82 mwifiex: Make resume actually do something useful again on SDIO cards
--
https://patchwork.kernel.org/patch/10884883/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* RE: [PATCH v8 13/15] x86/split_lock: Enable split lock detection by default
From: Thomas Gleixner @ 2019-04-25 10:58 UTC (permalink / raw)
To: David Laight
Cc: 'Fenghua Yu', Ingo Molnar, Borislav Petkov, H Peter Anvin,
Paolo Bonzini, Dave Hansen, Ashok Raj, Peter Zijlstra,
Ravi V Shankar, Xiaoyao Li, Christopherson Sean J, Kalle Valo,
Michael Chan, linux-kernel, x86, kvm@vger.kernel.org,
netdev@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <762682ba43a0468897ff5ddbf6633d58@AcuMS.aculab.com>
On Thu, 25 Apr 2019, David Laight wrote:
> From: Fenghua Yu
> > Sent: 24 April 2019 20:33
> > A split locked access locks bus and degrades overall memory access
> > performance. When split lock detection feature is enumerated, enable
> > the feature by default by writing 1 to bit 29 in MSR TEST_CTL to find
> > any split lock issue.
>
> You can't enable this by default until ALL the known potentially
> misaligned locked memory operations have been fixed.
Errm? The result will be a WARN_ON() printed and no further damage. It's
not making anything worse than it is now. In fact we just should add a
WARN_ON_ONCE(!aligned_to_long(p)) to all the xxx_bit() operations.
so we catch them even when they do not trigger that #AC thingy.
Thanks,
tglx
^ permalink raw reply
* RE: [PATCH v8 13/15] x86/split_lock: Enable split lock detection by default
From: David Laight @ 2019-04-25 10:52 UTC (permalink / raw)
To: 'Fenghua Yu', Thomas Gleixner, Ingo Molnar,
Borislav Petkov, H Peter Anvin, Paolo Bonzini, Dave Hansen,
Ashok Raj, Peter Zijlstra, Ravi V Shankar, Xiaoyao Li ,
Christopherson Sean J, Kalle Valo, Michael Chan
Cc: linux-kernel, x86, kvm@vger.kernel.org, netdev@vger.kernel.org,
linux-wireless@vger.kernel.org
In-Reply-To: <1556134382-58814-14-git-send-email-fenghua.yu@intel.com>
From: Fenghua Yu
> Sent: 24 April 2019 20:33
> A split locked access locks bus and degrades overall memory access
> performance. When split lock detection feature is enumerated, enable
> the feature by default by writing 1 to bit 29 in MSR TEST_CTL to find
> any split lock issue.
You can't enable this by default until ALL the known potentially
misaligned locked memory operations have been fixed.
AFAICT you've only fixed the ones that have actually faulted.
You've not even fixed the other ones in the same source files
as ones you've 'fixed'.
You need to do a code audit of all the in-tree kernel code
that uses locked operations - especially the 'bit' ones
since a lot of code casts the bitmap address - so it probably
isn't long aligned.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply
* Re: [PATCH v3 0/4] Add support for MediaTek MT7615 wireless chipsets
From: Felix Fietkau @ 2019-04-25 10:07 UTC (permalink / raw)
To: Ryder Lee, Lorenzo Bianconi
Cc: Roy Luo, Sean Wang, Nelson Chang, YF Luo, Kai Lin, Rorscha Yang,
Kyle Lee, Miller Shen, Haipin Liang, KL Huang, YH chen,
linux-wireless, linux-mediatek, linux-kernel
In-Reply-To: <cover.1554102584.git.ryder.lee@mediatek.com>
On 2019-04-01 09:16, Ryder Lee wrote:
> This adds support for MediaTek MT7615E 4x4 802.11ac PCIe-based chipsets.
>
> The series is based on the Lorenzo's patches:
> https://patchwork.kernel.org/project/linux-wireless/list/?series=95969
>
> In the legacy tx arch, we move and store the whole skb content to the
> on-device memory when we send packets via high speed interface. (e.g. PCIe)
>
> However, MT7615 and the following generation use a new tx arch called
> “cut-through”, which only passes the physical address to the hardware,
> and the packet engine will fetch the packets before transmission.
>
> It saves on-chip memory for high throughput devices, and the token mechanism
> is used to manage the release of skb under this arch.
>
> And there might be other (existing or future) chips that use the same driver
> (e.g. mt7622/mt7663...), this is a starting point to unify MTK wireless chipsets.
>
> Detailed hardware information for this chip could be found on
> https://wikidevi.com/wiki/MediaTek_MT7615
>
> Ryder Lee (4):
> mt76: add mac80211 driver for MT7615 PCIe-based chipsets
> mt76: add unlikely() for dma_mapping_error() check
> mt76: use macro for sn and seq_ctrl conversion
> MAINTAINERS : update entry for mt76 wireless driver
Applied, thanks.
- Felix
^ permalink raw reply
* Re: [PATCH v2 0/4] add missing bits for mt7615 support
From: Felix Fietkau @ 2019-04-25 10:06 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: ryder.lee, roychl666, lorenzo.bianconi, linux-wireless
In-Reply-To: <cover.1554194917.git.lorenzo@kernel.org>
On 2019-04-02 11:47, Lorenzo Bianconi wrote:
> This is a preliminary series to add support for mt7615.
> Dynamically allocate txwi descriptor.
> Add missing bit in dma error data path.
> This series is based on https://patchwork.kernel.org/patch/10856027/
>
> Changes since v1:
> - remove flags from mt76_txwi_cache
>
> Lorenzo Bianconi (4):
> mt76: set txwi_size according to the driver value
> mt76: add skb pointer to mt76_tx_info
> mt76: dma: introduce skb field in mt76_txwi_cache
> mt76: dma: add skb check for dummy pointer
Applied, thanks.
- Felix
^ permalink raw reply
* Re: [PATCH v2] mt76: usb: reduce locking in mt76u_tx_tasklet
From: Felix Fietkau @ 2019-04-25 9:59 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: linux-wireless, lorenzo.bianconi, sgruszka
In-Reply-To: <7e6146236dac0d616519e2a6e4b32fac9a1cae2f.1553541103.git.lorenzo@kernel.org>
On 2019-03-25 20:18, Lorenzo Bianconi wrote:
> Similar to pci counterpart, reduce locking in mt76u_tx_tasklet since
> q->head is managed just in mt76u_tx_tasklet and q->queued is updated
> holding q->lock
>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Applied, thanks.
- Felix
^ permalink raw reply
* Re: [PATCH v2] mt76: move mac_work in mt76_dev
From: Felix Fietkau @ 2019-04-25 9:59 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: linux-wireless, lorenzo.bianconi, sgruszka
In-Reply-To: <d4eb4aa6f8f8b003442b4f04b0f659e612486263.1552903068.git.lorenzo@kernel.org>
On 2019-03-18 11:21, Lorenzo Bianconi wrote:
> Move mac_work delayed work in mt76_dev data structure since
> it is used by all drivers and it will be reused adding mac work to
> mt7615
>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Applied, thanks.
- Felix
^ permalink raw reply
* Re: [PATCH v2 wireless-drivers-next] rtlwifi: rtl8723ae: Fix missing break in switch statement
From: Kalle Valo @ 2019-04-25 9:37 UTC (permalink / raw)
To: Gustavo A. R. Silva
Cc: Ping-Ke Shih, David S. Miller, Larry Finger, linux-wireless,
netdev, linux-kernel, Kees Cook
In-Reply-To: <6056eaca-5120-ec0f-6e72-2e1bfbde52a9@embeddedor.com>
"Gustavo A. R. Silva" <gustavo@embeddedor.com> writes:
> Hi all,
>
> Friendly ping:
>
> Who can take this?
It's in my queue.
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH 5/5] mac80211: set NETIF_F_LLTX when using intermediate tx queues
From: Herbert Xu @ 2019-04-25 8:35 UTC (permalink / raw)
To: Johannes Berg
Cc: Toke Høiland-Jørgensen, Arend Van Spriel, Felix Fietkau,
linux-wireless, Eric Dumazet, netdev
In-Reply-To: <99da695257304d32b65e2db8b7ada06759087c90.camel@sipsolutions.net>
On Tue, Apr 23, 2019 at 02:41:33PM +0200, Johannes Berg wrote:
>
> I guess there might be value in returning NET_XMIT_CN anyway, but I
> think you're right in that we can never return anything but
> NET_XMIT_SUCCESS or NET_XMIT_CN since we never drop this new packet,
> just older ones.
>
> Which, btw, is exactly the same with net/sched/sch_fq_codel.c, AFAICT?
Pretty sure codel does return NET_XMIT_CN.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH 5/5] mac80211: set NETIF_F_LLTX when using intermediate tx queues
From: Johannes Berg @ 2019-04-25 8:49 UTC (permalink / raw)
To: Herbert Xu
Cc: Toke Høiland-Jørgensen, Arend Van Spriel, Felix Fietkau,
linux-wireless, Eric Dumazet, netdev
In-Reply-To: <20190425084428.poni4y7mqox5up5t@gondor.apana.org.au>
On Thu, 2019-04-25 at 16:44 +0800, Herbert Xu wrote:
> On Thu, Apr 25, 2019 at 10:39:52AM +0200, Johannes Berg wrote:
> >
> > Yes, that's what I meant, it can only ever return NET_XMIT_SUCCESS or
> > NET_XMIT_CN. This will not trigger the code you mentioned before though.
>
> You are right that it does not. However, the fact that this
> congestion indication is lost is a bug rather than a feature.
You can argue that way, I guess.
However, *any* queue management algorithm that doesn't *solely* employ
tail drops will necessarily behave this way.
I would argue that you get better queue management if you don't solely
rely on tail drops, so I'd rather pick better queue management than this
(relatively obscure) congestion notification. The more commonly relevant
socket buffer size will work for both.
johannes
^ permalink raw reply
* Re: [PATCH 5/5] mac80211: set NETIF_F_LLTX when using intermediate tx queues
From: Herbert Xu @ 2019-04-25 8:44 UTC (permalink / raw)
To: Johannes Berg
Cc: Toke Høiland-Jørgensen, Arend Van Spriel, Felix Fietkau,
linux-wireless, Eric Dumazet, netdev
In-Reply-To: <0190c32f3d861d9d7a783090653645c5ae3a7fa3.camel@sipsolutions.net>
On Thu, Apr 25, 2019 at 10:39:52AM +0200, Johannes Berg wrote:
>
> Yes, that's what I meant, it can only ever return NET_XMIT_SUCCESS or
> NET_XMIT_CN. This will not trigger the code you mentioned before though.
You are right that it does not. However, the fact that this
congestion indication is lost is a bug rather than a feature.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH 5/5] mac80211: set NETIF_F_LLTX when using intermediate tx queues
From: Johannes Berg @ 2019-04-25 8:39 UTC (permalink / raw)
To: Herbert Xu
Cc: Toke Høiland-Jørgensen, Arend Van Spriel, Felix Fietkau,
linux-wireless, Eric Dumazet, netdev
In-Reply-To: <20190425083558.p3kqodaawr2jcfhr@gondor.apana.org.au>
On Thu, 2019-04-25 at 16:35 +0800, Herbert Xu wrote:
> On Tue, Apr 23, 2019 at 02:41:33PM +0200, Johannes Berg wrote:
> >
> > I guess there might be value in returning NET_XMIT_CN anyway, but I
> > think you're right in that we can never return anything but
> > NET_XMIT_SUCCESS or NET_XMIT_CN since we never drop this new packet,
> > just older ones.
> >
> > Which, btw, is exactly the same with net/sched/sch_fq_codel.c, AFAICT?
>
> Pretty sure codel does return NET_XMIT_CN.
Yes, that's what I meant, it can only ever return NET_XMIT_SUCCESS or
NET_XMIT_CN. This will not trigger the code you mentioned before though.
johannes
^ permalink raw reply
* [PATCH v2 2/5] mt76: reduce locking in mt76_dma_tx_cleanup
From: Felix Fietkau @ 2019-04-25 8:38 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <20190425083844.14186-1-nbd@nbd.name>
q->tail can be safely updated without locking, because there is no
concurrent access. If called from outside of the tasklet (for flushing),
the tasklet is always disabled.
q->queued can be safely read without locking, as long as the decrement
happens within the locked section.
This patch allows cleaning up tx packets outside of the section that holds
the queue lock for improved performance
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/dma.c | 26 ++++++++++++++++--------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 7145b75b6438..e4a5b34915bf 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -149,31 +149,29 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
struct mt76_sw_queue *sq = &dev->q_tx[qid];
struct mt76_queue *q = sq->q;
struct mt76_queue_entry entry;
+ unsigned int n_swq_queued[4] = {};
+ unsigned int n_queued = 0;
bool wake = false;
- int last;
+ int i, last;
if (!q)
return;
- spin_lock_bh(&q->lock);
if (flush)
last = -1;
else
last = readl(&q->regs->dma_idx);
- while (q->queued && q->tail != last) {
+ while ((q->queued > n_queued) && q->tail != last) {
mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry);
if (entry.schedule)
- dev->q_tx[entry.qid].swq_queued--;
+ n_swq_queued[entry.qid]++;
q->tail = (q->tail + 1) % q->ndesc;
- q->queued--;
+ n_queued++;
- if (entry.skb) {
- spin_unlock_bh(&q->lock);
+ if (entry.skb)
dev->drv->tx_complete_skb(dev, qid, &entry);
- spin_lock_bh(&q->lock);
- }
if (entry.txwi) {
mt76_put_txwi(dev, entry.txwi);
@@ -184,6 +182,16 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
last = readl(&q->regs->dma_idx);
}
+ spin_lock_bh(&q->lock);
+
+ q->queued -= n_queued;
+ for (i = 0; i < ARRAY_SIZE(n_swq_queued); i++) {
+ if (!n_swq_queued[i])
+ continue;
+
+ dev->q_tx[i].swq_queued -= n_swq_queued[i];
+ }
+
if (flush)
mt76_dma_sync_idx(dev, q);
--
2.17.0
^ permalink raw reply related
* [PATCH v2 5/5] mt76: only schedule txqs from the tx tasklet
From: Felix Fietkau @ 2019-04-25 8:38 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <20190425083844.14186-1-nbd@nbd.name>
Reduces lock contention from the tx path and improves performance
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/dma.c | 2 --
drivers/net/wireless/mediatek/mt76/mt7603/dma.c | 2 ++
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 3 +++
drivers/net/wireless/mediatek/mt76/tx.c | 2 +-
4 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index e4a5b34915bf..5c592566acbb 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -205,8 +205,6 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
spin_unlock_bh(&q->lock);
- if (!flush)
- mt76_txq_schedule(dev, qid);
if (wake)
ieee80211_wake_queue(dev->hw, qid);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
index f7e3566c96fd..27e2d9f90553 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
@@ -145,6 +145,8 @@ mt7603_tx_tasklet(unsigned long data)
for (i = MT_TXQ_MCU; i >= 0; i--)
mt76_queue_tx_cleanup(dev, i, false);
+ mt76_txq_schedule_all(&dev->mt76);
+
mt7603_irq_enable(dev, MT_INT_TX_DONE_ALL);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 958b2a3e4878..af308c0ef395 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -162,6 +162,9 @@ static void mt76x02_tx_tasklet(unsigned long data)
mt76_queue_tx_cleanup(dev, i, false);
mt76x02_mac_poll_tx_status(dev, false);
+
+ mt76_txq_schedule_all(&dev->mt76);
+
mt76x02_irq_enable(dev, MT_INT_TX_DONE_ALL);
}
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index dd0c583ab5b1..638b83903c56 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -595,7 +595,7 @@ void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
if (!test_bit(MT76_STATE_RUNNING, &dev->state))
return;
- mt76_txq_schedule(dev, txq->ac);
+ tasklet_schedule(&dev->tx_tasklet);
}
EXPORT_SYMBOL_GPL(mt76_wake_tx_queue);
--
2.17.0
^ permalink raw reply related
* [PATCH v2 4/5] mt76: move tx tasklet to struct mt76_dev
From: Felix Fietkau @ 2019-04-25 8:38 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <20190425083844.14186-1-nbd@nbd.name>
Allows it to be scheduled from core code
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 3 ++-
drivers/net/wireless/mediatek/mt76/mt7603/core.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt7603/dma.c | 4 ++--
drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 6 +++---
.../net/wireless/mediatek/mt76/mt7603/mt7603.h | 1 -
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 15 ++++++++-------
drivers/net/wireless/mediatek/mt76/mt76x2/usb.c | 2 +-
drivers/net/wireless/mediatek/mt76/usb.c | 6 +++---
9 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 176faaac8748..c35305ad2d12 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -386,7 +386,6 @@ struct mt76_usb {
u8 data[32];
struct tasklet_struct rx_tasklet;
- struct tasklet_struct tx_tasklet;
struct delayed_work stat_work;
u8 out_ep[__MT_EP_OUT_MAX];
@@ -448,6 +447,8 @@ struct mt76_dev {
const struct mt76_queue_ops *queue_ops;
int tx_dma_idx[4];
+ struct tasklet_struct tx_tasklet;
+
wait_queue_head_t tx_wait;
struct sk_buff_head status_list;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/core.c b/drivers/net/wireless/mediatek/mt76/mt7603/core.c
index 4668c573f74a..0d06ff67ce44 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/core.c
@@ -35,7 +35,7 @@ irqreturn_t mt7603_irq_handler(int irq, void *dev_instance)
if (intr & MT_INT_TX_DONE_ALL) {
mt7603_irq_disable(dev, MT_INT_TX_DONE_ALL);
- tasklet_schedule(&dev->tx_tasklet);
+ tasklet_schedule(&dev->mt76.tx_tasklet);
}
if (intr & MT_INT_RX_DONE(0)) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
index 37cedfcedce4..f7e3566c96fd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
@@ -164,7 +164,7 @@ int mt7603_dma_init(struct mt7603_dev *dev)
init_waitqueue_head(&dev->mt76.mmio.mcu.wait);
skb_queue_head_init(&dev->mt76.mmio.mcu.res_q);
- tasklet_init(&dev->tx_tasklet, mt7603_tx_tasklet, (unsigned long)dev);
+ tasklet_init(&dev->mt76.tx_tasklet, mt7603_tx_tasklet, (unsigned long)dev);
mt76_clear(dev, MT_WPDMA_GLO_CFG,
MT_WPDMA_GLO_CFG_TX_DMA_EN |
@@ -224,6 +224,6 @@ void mt7603_dma_cleanup(struct mt7603_dev *dev)
MT_WPDMA_GLO_CFG_RX_DMA_EN |
MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE);
- tasklet_kill(&dev->tx_tasklet);
+ tasklet_kill(&dev->mt76.tx_tasklet);
mt76_dma_cleanup(&dev->mt76);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 47f5005ea48a..52956bf8a979 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -1277,7 +1277,7 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)
/* lock/unlock all queues to ensure that no tx is pending */
mt76_txq_schedule_all(&dev->mt76);
- tasklet_disable(&dev->tx_tasklet);
+ tasklet_disable(&dev->mt76.tx_tasklet);
tasklet_disable(&dev->pre_tbtt_tasklet);
napi_disable(&dev->mt76.napi[0]);
napi_disable(&dev->mt76.napi[1]);
@@ -1324,8 +1324,8 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)
clear_bit(MT76_RESET, &dev->mt76.state);
mutex_unlock(&dev->mt76.mutex);
- tasklet_enable(&dev->tx_tasklet);
- tasklet_schedule(&dev->tx_tasklet);
+ tasklet_enable(&dev->mt76.tx_tasklet);
+ tasklet_schedule(&dev->mt76.tx_tasklet);
tasklet_enable(&dev->pre_tbtt_tasklet);
mt7603_beacon_set_timer(dev, -1, beacon_int);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index c355e36966dd..36875ff4c3bc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -145,7 +145,6 @@ struct mt7603_dev {
unsigned int reset_cause[__RESET_CAUSE_MAX];
struct delayed_work mac_work;
- struct tasklet_struct tx_tasklet;
struct tasklet_struct pre_tbtt_tasklet;
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 1ef00e971cfa..db2c3c6c2c66 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -332,7 +332,7 @@ static int __maybe_unused mt76x0_resume(struct usb_interface *usb_intf)
goto err;
tasklet_enable(&usb->rx_tasklet);
- tasklet_enable(&usb->tx_tasklet);
+ tasklet_enable(&dev->mt76.tx_tasklet);
ret = mt76x0u_init_hardware(dev);
if (ret)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 705c0939d10b..958b2a3e4878 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -180,7 +180,8 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
if (!status_fifo)
return -ENOMEM;
- tasklet_init(&dev->tx_tasklet, mt76x02_tx_tasklet, (unsigned long) dev);
+ tasklet_init(&dev->mt76.tx_tasklet, mt76x02_tx_tasklet,
+ (unsigned long) dev);
tasklet_init(&dev->pre_tbtt_tasklet, mt76x02_pre_tbtt_tasklet,
(unsigned long)dev);
@@ -250,7 +251,7 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance)
if (intr & MT_INT_TX_DONE_ALL) {
mt76x02_irq_disable(dev, MT_INT_TX_DONE_ALL);
- tasklet_schedule(&dev->tx_tasklet);
+ tasklet_schedule(&dev->mt76.tx_tasklet);
}
if (intr & MT_INT_RX_DONE(0)) {
@@ -276,7 +277,7 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance)
if (intr & MT_INT_TX_STAT) {
mt76x02_mac_poll_tx_status(dev, true);
- tasklet_schedule(&dev->tx_tasklet);
+ tasklet_schedule(&dev->mt76.tx_tasklet);
}
if (intr & MT_INT_GPTIMER) {
@@ -306,7 +307,7 @@ static void mt76x02_dma_enable(struct mt76x02_dev *dev)
void mt76x02_dma_cleanup(struct mt76x02_dev *dev)
{
- tasklet_kill(&dev->tx_tasklet);
+ tasklet_kill(&dev->mt76.tx_tasklet);
mt76_dma_cleanup(&dev->mt76);
}
EXPORT_SYMBOL_GPL(mt76x02_dma_cleanup);
@@ -425,7 +426,7 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
set_bit(MT76_RESET, &dev->mt76.state);
tasklet_disable(&dev->pre_tbtt_tasklet);
- tasklet_disable(&dev->tx_tasklet);
+ tasklet_disable(&dev->mt76.tx_tasklet);
for (i = 0; i < ARRAY_SIZE(dev->mt76.napi); i++)
napi_disable(&dev->mt76.napi[i]);
@@ -478,8 +479,8 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
clear_bit(MT76_RESET, &dev->mt76.state);
- tasklet_enable(&dev->tx_tasklet);
- tasklet_schedule(&dev->tx_tasklet);
+ tasklet_enable(&dev->mt76.tx_tasklet);
+ tasklet_schedule(&dev->mt76.tx_tasklet);
tasklet_enable(&dev->pre_tbtt_tasklet);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
index d08bb964966b..d1bddd5931bd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
@@ -124,7 +124,7 @@ static int __maybe_unused mt76x2u_resume(struct usb_interface *intf)
goto err;
tasklet_enable(&usb->rx_tasklet);
- tasklet_enable(&usb->tx_tasklet);
+ tasklet_enable(&dev->mt76.tx_tasklet);
err = mt76x2u_init_hardware(dev);
if (err < 0)
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index d93dadce95ab..15aeda0582e7 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -702,7 +702,7 @@ static void mt76u_complete_tx(struct urb *urb)
dev_err(dev->dev, "tx urb failed: %d\n", urb->status);
e->done = true;
- tasklet_schedule(&dev->usb.tx_tasklet);
+ tasklet_schedule(&dev->tx_tasklet);
}
static int
@@ -843,7 +843,7 @@ static void mt76u_stop_tx(struct mt76_dev *dev)
void mt76u_stop_queues(struct mt76_dev *dev)
{
tasklet_disable(&dev->usb.rx_tasklet);
- tasklet_disable(&dev->usb.tx_tasklet);
+ tasklet_disable(&dev->tx_tasklet);
mt76u_stop_rx(dev);
mt76u_stop_tx(dev);
@@ -898,7 +898,7 @@ int mt76u_init(struct mt76_dev *dev,
struct mt76_usb *usb = &dev->usb;
tasklet_init(&usb->rx_tasklet, mt76u_rx_tasklet, (unsigned long)dev);
- tasklet_init(&usb->tx_tasklet, mt76u_tx_tasklet, (unsigned long)dev);
+ tasklet_init(&dev->tx_tasklet, mt76u_tx_tasklet, (unsigned long)dev);
INIT_DELAYED_WORK(&usb->stat_work, mt76u_tx_status_data);
skb_queue_head_init(&dev->rx_skb[MT_RXQ_MAIN]);
--
2.17.0
^ permalink raw reply related
* [PATCH v2 1/5] mt76: use mac80211 txq scheduling
From: Felix Fietkau @ 2019-04-25 8:38 UTC (permalink / raw)
To: linux-wireless
Performance improvement and preparation for adding airtime fairness support
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/dma.c | 6 +-
drivers/net/wireless/mediatek/mt76/mac80211.c | 15 +++
drivers/net/wireless/mediatek/mt76/mt76.h | 3 +-
drivers/net/wireless/mediatek/mt76/tx.c | 101 ++++++++----------
drivers/net/wireless/mediatek/mt76/usb.c | 3 +-
5 files changed, 67 insertions(+), 61 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index cdeca22bf3a7..7145b75b6438 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -184,9 +184,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
last = readl(&q->regs->dma_idx);
}
- if (!flush)
- mt76_txq_schedule(dev, sq);
- else
+ if (flush)
mt76_dma_sync_idx(dev, q);
wake = wake && q->stopped &&
@@ -199,6 +197,8 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
spin_unlock_bh(&q->lock);
+ if (!flush)
+ mt76_txq_schedule(dev, qid);
if (wake)
ieee80211_wake_queue(dev->hw, qid);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 4b63d061c2a0..60b86ca00b3d 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -568,6 +568,7 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
struct ieee80211_sta *sta;
struct mt76_wcid *wcid = status->wcid;
bool ps;
+ int i;
if (ieee80211_is_pspoll(hdr->frame_control) && !wcid) {
sta = ieee80211_find_sta_by_ifaddr(dev->hw, hdr->addr2, NULL);
@@ -614,6 +615,20 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
dev->drv->sta_ps(dev, sta, ps);
ieee80211_sta_ps_transition(sta, ps);
+
+ if (ps)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
+ struct mt76_txq *mtxq;
+
+ if (!sta->txq[i])
+ continue;
+
+ mtxq = (struct mt76_txq *) sta->txq[i]->drv_priv;
+ if (!skb_queue_empty(&mtxq->retry_q))
+ ieee80211_schedule_txq(dev->hw, sta->txq[i]);
+ }
}
void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index f0d34901c825..e68834ee8393 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -216,7 +216,6 @@ struct mt76_wcid {
};
struct mt76_txq {
- struct list_head list;
struct mt76_sw_queue *swq;
struct mt76_wcid *wcid;
@@ -676,7 +675,7 @@ void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq);
void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta,
bool send_bar);
-void mt76_txq_schedule(struct mt76_dev *dev, struct mt76_sw_queue *sq);
+void mt76_txq_schedule(struct mt76_dev *dev, enum mt76_txq_id qid);
void mt76_txq_schedule_all(struct mt76_dev *dev);
void mt76_release_buffered_frames(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 2c82db0b5834..48f588726b3f 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -479,23 +479,37 @@ mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_sw_queue *sq,
}
static int
-mt76_txq_schedule_list(struct mt76_dev *dev, struct mt76_sw_queue *sq)
+mt76_txq_schedule_list(struct mt76_dev *dev, enum mt76_txq_id qid)
{
+ struct mt76_sw_queue *sq = &dev->q_tx[qid];
struct mt76_queue *hwq = sq->q;
- struct mt76_txq *mtxq, *mtxq_last;
- int len = 0;
+ struct ieee80211_txq *txq;
+ struct mt76_txq *mtxq;
+ struct mt76_wcid *wcid;
+ int ret = 0;
-restart:
- mtxq_last = list_last_entry(&sq->swq, struct mt76_txq, list);
- while (!list_empty(&sq->swq)) {
+ spin_lock_bh(&hwq->lock);
+ while (1) {
bool empty = false;
- int cur;
+
+ if (sq->swq_queued >= 4)
+ break;
if (test_bit(MT76_OFFCHANNEL, &dev->state) ||
- test_bit(MT76_RESET, &dev->state))
- return -EBUSY;
+ test_bit(MT76_RESET, &dev->state)) {
+ ret = -EBUSY;
+ break;
+ }
+
+ txq = ieee80211_next_txq(dev->hw, qid);
+ if (!txq)
+ break;
+
+ mtxq = (struct mt76_txq *)txq->drv_priv;
+ wcid = mtxq->wcid;
+ if (wcid && test_bit(MT_WCID_FLAG_PS, &wcid->flags))
+ continue;
- mtxq = list_first_entry(&sq->swq, struct mt76_txq, list);
if (mtxq->send_bar && mtxq->aggr) {
struct ieee80211_txq *txq = mtxq_to_txq(mtxq);
struct ieee80211_sta *sta = txq->sta;
@@ -507,38 +521,37 @@ mt76_txq_schedule_list(struct mt76_dev *dev, struct mt76_sw_queue *sq)
spin_unlock_bh(&hwq->lock);
ieee80211_send_bar(vif, sta->addr, tid, agg_ssn);
spin_lock_bh(&hwq->lock);
- goto restart;
}
- list_del_init(&mtxq->list);
-
- cur = mt76_txq_send_burst(dev, sq, mtxq, &empty);
- if (!empty)
- list_add_tail(&mtxq->list, &sq->swq);
-
- if (cur < 0)
- return cur;
-
- len += cur;
-
- if (mtxq == mtxq_last)
- break;
+ ret += mt76_txq_send_burst(dev, sq, mtxq, &empty);
+ if (skb_queue_empty(&mtxq->retry_q))
+ empty = true;
+ ieee80211_return_txq(dev->hw, txq, !empty);
}
+ spin_unlock_bh(&hwq->lock);
- return len;
+ return ret;
}
-void mt76_txq_schedule(struct mt76_dev *dev, struct mt76_sw_queue *sq)
+void mt76_txq_schedule(struct mt76_dev *dev, enum mt76_txq_id qid)
{
+ struct mt76_sw_queue *sq = &dev->q_tx[qid];
int len;
+ if (qid >= 4)
+ return;
+
+ if (sq->swq_queued >= 4)
+ return;
+
rcu_read_lock();
- do {
- if (sq->swq_queued >= 4 || list_empty(&sq->swq))
- break;
- len = mt76_txq_schedule_list(dev, sq);
+ do {
+ ieee80211_txq_schedule_start(dev->hw, qid);
+ len = mt76_txq_schedule_list(dev, qid);
+ ieee80211_txq_schedule_end(dev->hw, qid);
} while (len > 0);
+
rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(mt76_txq_schedule);
@@ -547,13 +560,8 @@ void mt76_txq_schedule_all(struct mt76_dev *dev)
{
int i;
- for (i = 0; i <= MT_TXQ_BK; i++) {
- struct mt76_queue *q = dev->q_tx[i].q;
-
- spin_lock_bh(&q->lock);
- mt76_txq_schedule(dev, &dev->q_tx[i]);
- spin_unlock_bh(&q->lock);
- }
+ for (i = 0; i <= MT_TXQ_BK; i++)
+ mt76_txq_schedule(dev, i);
}
EXPORT_SYMBOL_GPL(mt76_txq_schedule_all);
@@ -575,8 +583,6 @@ void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta,
spin_lock_bh(&hwq->lock);
mtxq->send_bar = mtxq->aggr && send_bar;
- if (!list_empty(&mtxq->list))
- list_del_init(&mtxq->list);
spin_unlock_bh(&hwq->lock);
}
}
@@ -585,24 +591,16 @@ EXPORT_SYMBOL_GPL(mt76_stop_tx_queues);
void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
{
struct mt76_dev *dev = hw->priv;
- struct mt76_txq *mtxq = (struct mt76_txq *)txq->drv_priv;
- struct mt76_sw_queue *sq = mtxq->swq;
- struct mt76_queue *hwq = sq->q;
if (!test_bit(MT76_STATE_RUNNING, &dev->state))
return;
- spin_lock_bh(&hwq->lock);
- if (list_empty(&mtxq->list))
- list_add_tail(&mtxq->list, &sq->swq);
- mt76_txq_schedule(dev, sq);
- spin_unlock_bh(&hwq->lock);
+ mt76_txq_schedule(dev, txq->ac);
}
EXPORT_SYMBOL_GPL(mt76_wake_tx_queue);
void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq)
{
- struct mt76_queue *hwq;
struct mt76_txq *mtxq;
struct sk_buff *skb;
@@ -610,12 +608,6 @@ void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq)
return;
mtxq = (struct mt76_txq *) txq->drv_priv;
- hwq = mtxq->swq->q;
-
- spin_lock_bh(&hwq->lock);
- if (!list_empty(&mtxq->list))
- list_del_init(&mtxq->list);
- spin_unlock_bh(&hwq->lock);
while ((skb = skb_dequeue(&mtxq->retry_q)) != NULL)
ieee80211_free_txskb(dev->hw, skb);
@@ -626,7 +618,6 @@ void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq)
{
struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
- INIT_LIST_HEAD(&mtxq->list);
skb_queue_head_init(&mtxq->retry_q);
mtxq->swq = &dev->q_tx[mt76_txq_get_qid(txq)];
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index a3acc070063a..d93dadce95ab 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -645,7 +645,6 @@ static void mt76u_tx_tasklet(unsigned long data)
dev->drv->tx_complete_skb(dev, i, &entry);
spin_lock_bh(&q->lock);
}
- mt76_txq_schedule(dev, sq);
wake = q->stopped && q->queued < q->ndesc - 8;
if (wake)
@@ -656,6 +655,8 @@ static void mt76u_tx_tasklet(unsigned long data)
spin_unlock_bh(&q->lock);
+ mt76_txq_schedule(dev, i);
+
if (!test_and_set_bit(MT76_READING_STATS, &dev->state))
ieee80211_queue_delayed_work(dev->hw,
&dev->usb.stat_work,
--
2.17.0
^ permalink raw reply related
* [PATCH v2 3/5] mt76: store wcid tx rate info in one u32 reduce locking
From: Felix Fietkau @ 2019-04-25 8:38 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <20190425083844.14186-1-nbd@nbd.name>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 10 ++++---
.../net/wireless/mediatek/mt76/mt7603/mac.c | 4 +--
.../net/wireless/mediatek/mt76/mt76x02_mac.c | 26 ++++++++++++-------
.../net/wireless/mediatek/mt76/mt76x02_util.c | 1 -
drivers/net/wireless/mediatek/mt76/tx.c | 4 +--
5 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index e68834ee8393..176faaac8748 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -188,6 +188,11 @@ enum mt76_wcid_flags {
DECLARE_EWMA(signal, 10, 8);
+#define MT_WCID_TX_INFO_RATE GENMASK(15, 0)
+#define MT_WCID_TX_INFO_NSS GENMASK(17, 16)
+#define MT_WCID_TX_INFO_TXPWR_ADJ GENMASK(25, 18)
+#define MT_WCID_TX_INFO_SET BIT(31)
+
struct mt76_wcid {
struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS];
@@ -206,10 +211,7 @@ struct mt76_wcid {
u8 rx_check_pn;
u8 rx_key_pn[IEEE80211_NUM_TIDS][6];
- __le16 tx_rate;
- bool tx_rate_set;
- u8 tx_rate_nss;
- s8 max_txpwr_adj;
+ u32 tx_info;
bool sw_iv;
u8 packet_id;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 2d090dacb788..47f5005ea48a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -717,11 +717,11 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta,
MT_WTBL_UPDATE_RATE_UPDATE |
MT_WTBL_UPDATE_TX_COUNT_CLEAR);
- if (!sta->wcid.tx_rate_set)
+ if (!(sta->wcid.tx_info & MT_WCID_TX_INFO_SET))
mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000);
sta->rate_count = 2 * MT7603_RATE_RETRY * n_rates;
- sta->wcid.tx_rate_set = true;
+ sta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
}
static enum mt7603_cipher_type
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 4a77d509a86b..b81b71ba0930 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -218,10 +218,17 @@ mt76x02_mac_tx_rate_val(struct mt76x02_dev *dev,
void mt76x02_mac_wcid_set_rate(struct mt76x02_dev *dev, struct mt76_wcid *wcid,
const struct ieee80211_tx_rate *rate)
{
- spin_lock_bh(&dev->mt76.lock);
- wcid->tx_rate = mt76x02_mac_tx_rate_val(dev, rate, &wcid->tx_rate_nss);
- wcid->tx_rate_set = true;
- spin_unlock_bh(&dev->mt76.lock);
+ s8 max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, rate);
+ __le16 rateval;
+ u32 tx_info;
+ s8 nss;
+
+ rateval = mt76x02_mac_tx_rate_val(dev, rate, &nss);
+ tx_info = FIELD_PREP(MT_WCID_TX_INFO_RATE, rateval) |
+ FIELD_PREP(MT_WCID_TX_INFO_NSS, nss) |
+ FIELD_PREP(MT_WCID_TX_INFO_TXPWR_ADJ, max_txpwr_adj) |
+ MT_WCID_TX_INFO_SET;
+ wcid->tx_info = tx_info;
}
void mt76x02_mac_set_short_preamble(struct mt76x02_dev *dev, bool enable)
@@ -323,6 +330,7 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rate = &info->control.rates[0];
struct ieee80211_key_conf *key = info->control.hw_key;
+ u32 wcid_tx_info;
u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2));
u16 txwi_flags = 0;
u8 nss;
@@ -357,16 +365,16 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
txwi->eiv = *((__le32 *)&ccmp_pn[4]);
}
- spin_lock_bh(&dev->mt76.lock);
if (wcid && (rate->idx < 0 || !rate->count)) {
- txwi->rate = wcid->tx_rate;
- max_txpwr_adj = wcid->max_txpwr_adj;
- nss = wcid->tx_rate_nss;
+ wcid_tx_info = wcid->tx_info;
+ txwi->rate = FIELD_GET(MT_WCID_TX_INFO_RATE, wcid_tx_info);
+ max_txpwr_adj = FIELD_GET(MT_WCID_TX_INFO_TXPWR_ADJ,
+ wcid_tx_info);
+ nss = FIELD_GET(MT_WCID_TX_INFO_NSS, wcid_tx_info);
} else {
txwi->rate = mt76x02_mac_tx_rate_val(dev, rate, &nss);
max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, rate);
}
- spin_unlock_bh(&dev->mt76.lock);
txpwr_adj = mt76x02_tx_get_txpwr_adj(dev, dev->mt76.txpower_conf,
max_txpwr_adj);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 284dae65cdf1..f3558c108b17 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -572,7 +572,6 @@ void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw,
rate.idx = rates->rate[0].idx;
rate.flags = rates->rate[0].flags;
mt76x02_mac_wcid_set_rate(dev, &msta->wcid, &rate);
- msta->wcid.max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, &rate);
}
EXPORT_SYMBOL_GPL(mt76x02_sta_rate_tbl_update);
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 48f588726b3f..dd0c583ab5b1 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -266,7 +266,7 @@ mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
skb_set_queue_mapping(skb, qid);
}
- if (!wcid->tx_rate_set)
+ if (!(wcid->tx_info & MT_WCID_TX_INFO_SET))
ieee80211_get_tx_rates(info->control.vif, sta, skb,
info->control.rates, 1);
@@ -412,7 +412,7 @@ mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_sw_queue *sq,
}
info = IEEE80211_SKB_CB(skb);
- if (!wcid->tx_rate_set)
+ if (!(wcid->tx_info & MT_WCID_TX_INFO_SET))
ieee80211_get_tx_rates(txq->vif, txq->sta, skb,
info->control.rates, 1);
tx_rate = info->control.rates[0];
--
2.17.0
^ permalink raw reply related
* [PATCH] brcmfmac: allocate msgbuf pktid from 1 to pktids array size
From: Wright Feng @ 2019-04-25 8:04 UTC (permalink / raw)
To: arend.vanspriel@broadcom.com, franky.lin@broadcom.com,
hante.meuleman@broadcom.com, kvalo@codeaurora.org, Chi-Hsien Lin
Cc: Wright Feng, linux-wireless@vger.kernel.org,
brcm80211-dev-list.pdl@broadcom.com
Some PCIE firmwares drop txstatus if pktid is 0 and make packet held in
host side and not be released. If that packet type is 802.1x, the
pend_8021x_cnt value will be always greater than 0 and show "Timed out
waiting for no pending 802.1x packets" error message when sending key to
dongle.
To be compatible with all firmwares, host should allocate msgbuf pktid
from 1 instead of from 0.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index d3780ea..b2fab3c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -348,7 +348,7 @@ brcmf_msgbuf_alloc_pktid(struct device *dev,
do {
(*idx)++;
if (*idx == pktids->array_size)
- *idx = 0;
+ *idx = 1;
if (array[*idx].allocated.counter == 0)
if (atomic_cmpxchg(&array[*idx].allocated, 0, 1) == 0)
break;
--
2.1.0
^ permalink raw reply related
* Re: [PATCH v8 13/15] x86/split_lock: Enable split lock detection by default
From: Thomas Gleixner @ 2019-04-25 7:50 UTC (permalink / raw)
To: Fenghua Yu
Cc: Ingo Molnar, Borislav Petkov, H Peter Anvin, Paolo Bonzini,
Dave Hansen, Ashok Raj, Peter Zijlstra, Ravi V Shankar,
Xiaoyao Li, Christopherson Sean J, Kalle Valo, Michael Chan,
linux-kernel, x86, kvm, netdev, linux-wireless
In-Reply-To: <1556134382-58814-14-git-send-email-fenghua.yu@intel.com>
On Wed, 24 Apr 2019, Fenghua Yu wrote:
>
> +static void split_lock_update_msr(void)
> +{
> + /* Enable split lock detection */
> + msr_set_bit(MSR_TEST_CTL, TEST_CTL_SPLIT_LOCK_DETECT_SHIFT);
> + this_cpu_or(msr_test_ctl_cache, TEST_CTL_SPLIT_LOCK_DETECT);
I'm pretty sure, that I told you to utilize the cache proper. Again:
> > Nothing in this file initializes msr_test_ctl_cache explicitely. Register
> > caching always requires to read the register and store it in the cache
> > before doing anything with it. Nothing guarantees that all bits in that MSR
> > are 0 by default forever.
> >
> > And once you do that _before_ calling split_lock_update_msr() then you can
> > spare the RMW in that function.
So you managed to fix the initializaiton part, but then you still do a
pointless RMW.
Thanks,
tglx
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox