mwifiex: avoid queue_work while work is ongoing

Current code does not check whether main_work_queue or
rx_work_queue is running when preparing to do queue_work,
this code fix add check before calling queue_work, reducing
unnecessary queue_work switch.

This change instead sets more_task flag to ensure we run main_process
superloop once again.

Signed-off-by: Shengzhen Li <szli@marvell.com>
Signed-off-by: Zhaoyang Liu <liuzy@marvell.com>
Reviewed-by: Cathy Luo <cluo@marvell.com>
Reviewed-by: Amitkumar Karwar <akarwar@marvell.com>
Reviewed-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Shengzhen Li 2015-03-13 17:37:54 +05:30 committed by Kalle Valo
parent ea44f4d04c
commit b2713f67f7
4 changed files with 36 additions and 9 deletions

View File

@ -131,6 +131,34 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
return 0;
}
void mwifiex_queue_main_work(struct mwifiex_adapter *adapter)
{
unsigned long flags;
spin_lock_irqsave(&adapter->main_proc_lock, flags);
if (adapter->mwifiex_processing) {
adapter->more_task_flag = true;
spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
} else {
spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
queue_work(adapter->workqueue, &adapter->main_work);
}
}
EXPORT_SYMBOL_GPL(mwifiex_queue_main_work);
static void mwifiex_queue_rx_work(struct mwifiex_adapter *adapter)
{
unsigned long flags;
spin_lock_irqsave(&adapter->rx_proc_lock, flags);
if (adapter->rx_processing) {
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
} else {
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
queue_work(adapter->rx_workqueue, &adapter->rx_work);
}
}
static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
{
unsigned long flags;
@ -154,7 +182,7 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
if (adapter->if_ops.submit_rem_rx_urbs)
adapter->if_ops.submit_rem_rx_urbs(adapter);
adapter->delay_main_work = false;
queue_work(adapter->workqueue, &adapter->main_work);
mwifiex_queue_main_work(adapter);
}
mwifiex_handle_rx_packet(adapter, skb);
}
@ -214,9 +242,7 @@ process_start:
if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING &&
adapter->iface_type != MWIFIEX_USB) {
adapter->delay_main_work = true;
if (!adapter->rx_processing)
queue_work(adapter->rx_workqueue,
&adapter->rx_work);
mwifiex_queue_rx_work(adapter);
break;
}
@ -229,7 +255,7 @@ process_start:
}
if (adapter->rx_work_enabled && adapter->data_received)
queue_work(adapter->rx_workqueue, &adapter->rx_work);
mwifiex_queue_rx_work(adapter);
/* Need to wake up the card ? */
if ((adapter->ps_state == PS_STATE_SLEEP) &&
@ -606,7 +632,7 @@ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
atomic_inc(&priv->adapter->tx_pending);
mwifiex_wmm_add_buf_txqueue(priv, skb);
queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
mwifiex_queue_main_work(priv->adapter);
return 0;
}

View File

@ -1424,6 +1424,7 @@ u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter);
void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags);
void mwifiex_queue_main_work(struct mwifiex_adapter *adapter);
#ifdef CONFIG_DEBUG_FS
void mwifiex_debugfs_init(void);

View File

@ -2101,7 +2101,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
goto exit;
mwifiex_interrupt_status(adapter);
queue_work(adapter->workqueue, &adapter->main_work);
mwifiex_queue_main_work(adapter);
exit:
return IRQ_HANDLED;

View File

@ -193,7 +193,7 @@ static void mwifiex_usb_rx_complete(struct urb *urb)
dev_dbg(adapter->dev, "info: recv_length=%d, status=%d\n",
recv_length, status);
if (status == -EINPROGRESS) {
queue_work(adapter->workqueue, &adapter->main_work);
mwifiex_queue_main_work(adapter);
/* urb for data_ep is re-submitted now;
* urb for cmd_ep will be re-submitted in callback
@ -262,7 +262,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
urb->status ? -1 : 0);
}
queue_work(adapter->workqueue, &adapter->main_work);
mwifiex_queue_main_work(adapter);
return;
}