Skip to content

Commit e4e9bfb

Browse files
Alex Elderdavem330
authored andcommitted
net: ipa: kill ipa_cmd_pipeline_clear()
Calling ipa_cmd_pipeline_clear() after stopping the channel underlying the AP<-modem RX endpoint can lead to a deadlock. This occurs in the ->runtime_suspend device power operation for the IPA driver. While this callback is in progress, any other requests for power will block until the callback returns. Stopping the AP<-modem RX channel does not prevent the modem from sending another packet to this endpoint. If a packet arrives for an RX channel when the channel is stopped, an SUSPEND IPA interrupt condition will be pending. Handling an IPA interrupt requires power, so ipa_isr_thread() calls pm_runtime_get_sync() first thing. The problem occurs because a "pipeline clear" command will not complete while such a SUSPEND interrupt condition exists. So the SUSPEND IPA interrupt handler won't proceed until it gets power; that won't happen until the ->runtime_suspend callback (and its "pipeline clear" command) completes; and that can't happen while the SUSPEND interrupt condition exists. It turns out that in this case there is no need to use the "pipeline clear" command. There are scenarios in which clearing the pipeline is required while suspending, but those are not (yet) supported upstream. So a simple fix, avoiding the potential deadlock, is to stop calling ipa_cmd_pipeline_clear() in ipa_endpoint_suspend(). This removes the only user of ipa_cmd_pipeline_clear(), so get rid of that function. It can be restored again whenever it's needed. This is basically a manual revert along with an explanation for commit 6cb63ea ("net: ipa: introduce ipa_cmd_tag_process()"). Fixes: 6cb63ea ("net: ipa: introduce ipa_cmd_tag_process()") Signed-off-by: Alex Elder <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a049a30 commit e4e9bfb

File tree

3 files changed

+0
-24
lines changed

3 files changed

+0
-24
lines changed

drivers/net/ipa/ipa_cmd.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -661,22 +661,6 @@ void ipa_cmd_pipeline_clear_wait(struct ipa *ipa)
661661
wait_for_completion(&ipa->completion);
662662
}
663663

664-
void ipa_cmd_pipeline_clear(struct ipa *ipa)
665-
{
666-
u32 count = ipa_cmd_pipeline_clear_count();
667-
struct gsi_trans *trans;
668-
669-
trans = ipa_cmd_trans_alloc(ipa, count);
670-
if (trans) {
671-
ipa_cmd_pipeline_clear_add(trans);
672-
gsi_trans_commit_wait(trans);
673-
ipa_cmd_pipeline_clear_wait(ipa);
674-
} else {
675-
dev_err(&ipa->pdev->dev,
676-
"error allocating %u entry tag transaction\n", count);
677-
}
678-
}
679-
680664
static struct ipa_cmd_info *
681665
ipa_cmd_info_alloc(struct ipa_endpoint *endpoint, u32 tre_count)
682666
{

drivers/net/ipa/ipa_cmd.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,6 @@ u32 ipa_cmd_pipeline_clear_count(void);
163163
*/
164164
void ipa_cmd_pipeline_clear_wait(struct ipa *ipa);
165165

166-
/**
167-
* ipa_cmd_pipeline_clear() - Clear the hardware pipeline
168-
* @ipa: - IPA pointer
169-
*/
170-
void ipa_cmd_pipeline_clear(struct ipa *ipa);
171-
172166
/**
173167
* ipa_cmd_trans_alloc() - Allocate a transaction for the command TX endpoint
174168
* @ipa: IPA pointer

drivers/net/ipa/ipa_endpoint.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,8 +1636,6 @@ void ipa_endpoint_suspend(struct ipa *ipa)
16361636
if (ipa->modem_netdev)
16371637
ipa_modem_suspend(ipa->modem_netdev);
16381638

1639-
ipa_cmd_pipeline_clear(ipa);
1640-
16411639
ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]);
16421640
ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]);
16431641
}

0 commit comments

Comments
 (0)