]>
Commit | Line | Data |
---|---|---|
ba172962 SL |
1 | From 4ece01f77b31688263afc93c1104cdd71b1e2e79 Mon Sep 17 00:00:00 2001 |
2 | From: Sara Sharon <sara.sharon@intel.com> | |
3 | Date: Thu, 13 Dec 2018 14:47:40 +0200 | |
4 | Subject: iwlwifi: pcie: fix emergency path | |
5 | ||
6 | [ Upstream commit c6ac9f9fb98851f47b978a9476594fc3c477a34d ] | |
7 | ||
8 | Allocator swaps the pending requests with 0 when it starts | |
9 | working. This means that relying on it n RX path to decide if | |
10 | to move to emergency is not always a good idea, since it may | |
11 | be zero, but there are still a lot of unallocated RBs in the | |
12 | system. Change allocator to decrement the pending requests on | |
13 | real time. It is more expensive since it accesses the atomic | |
14 | variable more times, but it gives the RX path a better idea | |
15 | of the system's status. | |
16 | ||
17 | Reported-by: Ilan Peer <ilan.peer@intel.com> | |
18 | Signed-off-by: Sara Sharon <sara.sharon@intel.com> | |
19 | Fixes: 868a1e863f95 ("iwlwifi: pcie: avoid empty free RB queue") | |
20 | Signed-off-by: Luca Coelho <luciano.coelho@intel.com> | |
21 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
22 | --- | |
23 | drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 11 ++++++++--- | |
24 | 1 file changed, 8 insertions(+), 3 deletions(-) | |
25 | ||
26 | diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c | |
27 | index d4a31e014c82..b2905f01b7df 100644 | |
28 | --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c | |
29 | +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c | |
30 | @@ -502,7 +502,7 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans) | |
31 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | |
32 | struct iwl_rb_allocator *rba = &trans_pcie->rba; | |
33 | struct list_head local_empty; | |
34 | - int pending = atomic_xchg(&rba->req_pending, 0); | |
35 | + int pending = atomic_read(&rba->req_pending); | |
36 | ||
37 | IWL_DEBUG_RX(trans, "Pending allocation requests = %d\n", pending); | |
38 | ||
39 | @@ -557,11 +557,13 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans) | |
40 | i++; | |
41 | } | |
42 | ||
43 | + atomic_dec(&rba->req_pending); | |
44 | pending--; | |
45 | + | |
46 | if (!pending) { | |
47 | - pending = atomic_xchg(&rba->req_pending, 0); | |
48 | + pending = atomic_read(&rba->req_pending); | |
49 | IWL_DEBUG_RX(trans, | |
50 | - "Pending allocation requests = %d\n", | |
51 | + "Got more pending allocation requests = %d\n", | |
52 | pending); | |
53 | } | |
54 | ||
55 | @@ -573,12 +575,15 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans) | |
56 | spin_unlock(&rba->lock); | |
57 | ||
58 | atomic_inc(&rba->req_ready); | |
59 | + | |
60 | } | |
61 | ||
62 | spin_lock(&rba->lock); | |
63 | /* return unused rbds to the allocator empty list */ | |
64 | list_splice_tail(&local_empty, &rba->rbd_empty); | |
65 | spin_unlock(&rba->lock); | |
66 | + | |
67 | + IWL_DEBUG_RX(trans, "%s, exit.\n", __func__); | |
68 | } | |
69 | ||
70 | /* | |
71 | -- | |
72 | 2.19.1 | |
73 |