From: Douglas Anderson <dianders@chromium.org> To: kvalo@codeaurora.org Cc: kuabhs@google.com, pillair@codeaurora.org, saiprakash.ranjan@codeaurora.org, linux-arm-msm@vger.kernel.org, Douglas Anderson <dianders@chromium.org>, "David S. Miller" <davem@davemloft.net>, Jakub Kicinski <kuba@kernel.org>, ath10k@lists.infradead.org, linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH] ath10k: Wait until copy complete is actually done before completing Date: Tue, 9 Jun 2020 08:20:58 -0700 [thread overview] Message-ID: <20200609082015.1.Ife398994e5a0a6830e4d4a16306ef36e0144e7ba@changeid> (raw) On wcn3990 we have "per_ce_irq = true". That makes the ath10k_ce_interrupt_summary() function always return 0xfff. The ath10k_ce_per_engine_service_any() function will see this and think that _all_ copy engines have an interrupt. Without checking, the ath10k_ce_per_engine_service() assumes that if it's called that the "copy complete" (cc) interrupt fired. This combination seems bad. Let's add a check to make sure that the "copy complete" interrupt actually fired in ath10k_ce_per_engine_service(). This might fix a hard-to-reproduce failure where it appears that the copy complete handlers run before the copy is really complete. Specifically a symptom was that we were seeing this on a Qualcomm sc7180 board: arm-smmu 15000000.iommu: Unhandled context fault: fsr=0x402, iova=0x7fdd45780, fsynr=0x30003, cbfrsynra=0xc1, cb=10 Even on platforms that don't have wcn3990 this still seems like it would be a sane thing to do. Specifically the current IRQ handler comments indicate that there might be other misc interrupt sources firing that need to be cleared. If one of those sources was the one that caused the IRQ handler to be called it would also be important to double-check that the interrupt we cared about actually fired. Signed-off-by: Douglas Anderson <dianders@chromium.org> --- drivers/net/wireless/ath/ath10k/ce.c | 30 +++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 294fbc1e89ab..ffdd4b995f33 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -481,6 +481,15 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar, ath10k_ce_write32(ar, ce_ctrl_addr + wm_regs->addr, mask); } +static inline bool ath10k_ce_engine_int_status_check(struct ath10k *ar, + u32 ce_ctrl_addr, + unsigned int mask) +{ + struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs; + + return ath10k_ce_read32(ar, ce_ctrl_addr + wm_regs->addr) & mask; +} + /* * Guts of ath10k_ce_send. * The caller takes responsibility for any needed locking. @@ -1301,19 +1310,22 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) spin_lock_bh(&ce->ce_lock); - /* Clear the copy-complete interrupts that will be handled here. */ - ath10k_ce_engine_int_status_clear(ar, ctrl_addr, - wm_regs->cc_mask); + if (ath10k_ce_engine_int_status_check(ar, ctrl_addr, + wm_regs->cc_mask)) { + /* Clear before handling */ + ath10k_ce_engine_int_status_clear(ar, ctrl_addr, + wm_regs->cc_mask); - spin_unlock_bh(&ce->ce_lock); + spin_unlock_bh(&ce->ce_lock); - if (ce_state->recv_cb) - ce_state->recv_cb(ce_state); + if (ce_state->recv_cb) + ce_state->recv_cb(ce_state); - if (ce_state->send_cb) - ce_state->send_cb(ce_state); + if (ce_state->send_cb) + ce_state->send_cb(ce_state); - spin_lock_bh(&ce->ce_lock); + spin_lock_bh(&ce->ce_lock); + } /* * Misc CE interrupts are not being handled, but still need -- 2.27.0.278.ge193c7cf3a9-goog
WARNING: multiple messages have this Message-ID (diff)
From: Douglas Anderson <dianders@chromium.org> To: kvalo@codeaurora.org Cc: saiprakash.ranjan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-wireless@vger.kernel.org, Douglas Anderson <dianders@chromium.org>, ath10k@lists.infradead.org, linux-kernel@vger.kernel.org, pillair@codeaurora.org, netdev@vger.kernel.org, Jakub Kicinski <kuba@kernel.org>, "David S. Miller" <davem@davemloft.net>, kuabhs@google.com Subject: [PATCH] ath10k: Wait until copy complete is actually done before completing Date: Tue, 9 Jun 2020 08:20:58 -0700 [thread overview] Message-ID: <20200609082015.1.Ife398994e5a0a6830e4d4a16306ef36e0144e7ba@changeid> (raw) On wcn3990 we have "per_ce_irq = true". That makes the ath10k_ce_interrupt_summary() function always return 0xfff. The ath10k_ce_per_engine_service_any() function will see this and think that _all_ copy engines have an interrupt. Without checking, the ath10k_ce_per_engine_service() assumes that if it's called that the "copy complete" (cc) interrupt fired. This combination seems bad. Let's add a check to make sure that the "copy complete" interrupt actually fired in ath10k_ce_per_engine_service(). This might fix a hard-to-reproduce failure where it appears that the copy complete handlers run before the copy is really complete. Specifically a symptom was that we were seeing this on a Qualcomm sc7180 board: arm-smmu 15000000.iommu: Unhandled context fault: fsr=0x402, iova=0x7fdd45780, fsynr=0x30003, cbfrsynra=0xc1, cb=10 Even on platforms that don't have wcn3990 this still seems like it would be a sane thing to do. Specifically the current IRQ handler comments indicate that there might be other misc interrupt sources firing that need to be cleared. If one of those sources was the one that caused the IRQ handler to be called it would also be important to double-check that the interrupt we cared about actually fired. Signed-off-by: Douglas Anderson <dianders@chromium.org> --- drivers/net/wireless/ath/ath10k/ce.c | 30 +++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 294fbc1e89ab..ffdd4b995f33 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -481,6 +481,15 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar, ath10k_ce_write32(ar, ce_ctrl_addr + wm_regs->addr, mask); } +static inline bool ath10k_ce_engine_int_status_check(struct ath10k *ar, + u32 ce_ctrl_addr, + unsigned int mask) +{ + struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs; + + return ath10k_ce_read32(ar, ce_ctrl_addr + wm_regs->addr) & mask; +} + /* * Guts of ath10k_ce_send. * The caller takes responsibility for any needed locking. @@ -1301,19 +1310,22 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) spin_lock_bh(&ce->ce_lock); - /* Clear the copy-complete interrupts that will be handled here. */ - ath10k_ce_engine_int_status_clear(ar, ctrl_addr, - wm_regs->cc_mask); + if (ath10k_ce_engine_int_status_check(ar, ctrl_addr, + wm_regs->cc_mask)) { + /* Clear before handling */ + ath10k_ce_engine_int_status_clear(ar, ctrl_addr, + wm_regs->cc_mask); - spin_unlock_bh(&ce->ce_lock); + spin_unlock_bh(&ce->ce_lock); - if (ce_state->recv_cb) - ce_state->recv_cb(ce_state); + if (ce_state->recv_cb) + ce_state->recv_cb(ce_state); - if (ce_state->send_cb) - ce_state->send_cb(ce_state); + if (ce_state->send_cb) + ce_state->send_cb(ce_state); - spin_lock_bh(&ce->ce_lock); + spin_lock_bh(&ce->ce_lock); + } /* * Misc CE interrupts are not being handled, but still need -- 2.27.0.278.ge193c7cf3a9-goog _______________________________________________ ath10k mailing list ath10k@lists.infradead.org http://lists.infradead.org/mailman/listinfo/ath10k
next reply other threads:[~2020-06-09 15:21 UTC|newest] Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-06-09 15:20 Douglas Anderson [this message] 2020-06-09 15:20 ` [PATCH] ath10k: Wait until copy complete is actually done before completing Douglas Anderson 2020-06-12 14:25 ` pillair 2020-06-12 14:25 ` pillair 2020-06-15 14:32 ` Kalle Valo 2020-06-15 14:39 ` Doug Anderson 2020-06-15 14:39 ` Doug Anderson 2020-06-15 14:56 ` Kalle Valo 2020-06-15 14:56 ` Kalle Valo 2020-06-15 15:02 ` Doug Anderson 2020-06-15 15:02 ` Doug Anderson 2020-06-15 14:32 ` Kalle Valo 2020-06-16 8:11 ` Kalle Valo 2020-06-16 8:11 ` Kalle Valo
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=20200609082015.1.Ife398994e5a0a6830e4d4a16306ef36e0144e7ba@changeid \ --to=dianders@chromium.org \ --cc=ath10k@lists.infradead.org \ --cc=davem@davemloft.net \ --cc=kuabhs@google.com \ --cc=kuba@kernel.org \ --cc=kvalo@codeaurora.org \ --cc=linux-arm-msm@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-wireless@vger.kernel.org \ --cc=netdev@vger.kernel.org \ --cc=pillair@codeaurora.org \ --cc=saiprakash.ranjan@codeaurora.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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.