diff options
author | Mohamed Abbas <mohamed.abbas@intel.com> | 2009-05-22 14:01:51 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-05-22 14:06:08 -0400 |
commit | 4752c93c30441f98f7ed723001b1a5e3e5619829 (patch) | |
tree | de868a2003d2328ad3bd048e75bc16b7e327bd7f /drivers/net/wireless/iwlwifi/iwl-agn.c | |
parent | ef850d7cb301bda9155c096269557a4586b58071 (diff) |
iwlcore: Allow skb allocation from tasklet.
If RX queue becomes empty then we need to restock the queue from tasklet to prevent
ucode from starving. A caller to iwl_rx_allocate will decide if allocated buffer should
come from GFP_ATOMIC or GFP_KERNEL.
Signed-off-by: Mohamed Abbas <mohamed.abbas@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index fa24b019c62c..be1058bdc4c5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -831,6 +831,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
831 | unsigned long flags; | 831 | unsigned long flags; |
832 | u8 fill_rx = 0; | 832 | u8 fill_rx = 0; |
833 | u32 count = 8; | 833 | u32 count = 8; |
834 | int total_empty; | ||
834 | 835 | ||
835 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | 836 | /* uCode's read index (stored in shared DRAM) indicates the last Rx |
836 | * buffer that the driver may process (last buffer filled by ucode). */ | 837 | * buffer that the driver may process (last buffer filled by ucode). */ |
@@ -841,7 +842,12 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
841 | if (i == r) | 842 | if (i == r) |
842 | IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); | 843 | IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); |
843 | 844 | ||
844 | if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) | 845 | /* calculate total frames need to be restock after handling RX */ |
846 | total_empty = r - priv->rxq.write_actual; | ||
847 | if (total_empty < 0) | ||
848 | total_empty += RX_QUEUE_SIZE; | ||
849 | |||
850 | if (total_empty > (RX_QUEUE_SIZE / 2)) | ||
845 | fill_rx = 1; | 851 | fill_rx = 1; |
846 | 852 | ||
847 | while (i != r) { | 853 | while (i != r) { |
@@ -918,7 +924,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
918 | count++; | 924 | count++; |
919 | if (count >= 8) { | 925 | if (count >= 8) { |
920 | priv->rxq.read = i; | 926 | priv->rxq.read = i; |
921 | iwl_rx_queue_restock(priv); | 927 | iwl_rx_replenish_now(priv); |
922 | count = 0; | 928 | count = 0; |
923 | } | 929 | } |
924 | } | 930 | } |
@@ -926,7 +932,10 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
926 | 932 | ||
927 | /* Backtrack one entry */ | 933 | /* Backtrack one entry */ |
928 | priv->rxq.read = i; | 934 | priv->rxq.read = i; |
929 | iwl_rx_queue_restock(priv); | 935 | if (fill_rx) |
936 | iwl_rx_replenish_now(priv); | ||
937 | else | ||
938 | iwl_rx_queue_restock(priv); | ||
930 | } | 939 | } |
931 | 940 | ||
932 | /* call this function to flush any scheduled tasklet */ | 941 | /* call this function to flush any scheduled tasklet */ |