Skip to content

Commit

Permalink
wlcore: tx_flush - optimize flow and force Tx during the flush
Browse files Browse the repository at this point in the history
Force Tx during the flush if there are packets pending in the driver.
This actually solves a bug where we would get called from the mac80211
wq context, which would prevent tx_work from getting queued, even when
the mutex is unlocked.

Don't stop the queues needlessly if there's nothing to flush. Use a
larger delay when sleeping to give the driver a chance to flush and
avoid cpu busy looping. Re-arrange the loop so the last iteration is
not wasted.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <luca@coelho.fi>
  • Loading branch information
Arik Nemtsov authored and Luciano Coelho committed Sep 27, 2012
1 parent 958e303 commit f83e541
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions drivers/net/wireless/ti/wlcore/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1084,36 +1084,46 @@ void wl1271_tx_flush(struct wl1271 *wl)
/* only one flush should be in progress, for consistent queue state */
mutex_lock(&wl->flush_mutex);

mutex_lock(&wl->mutex);
if (wl->tx_frames_cnt == 0 && wl1271_tx_total_queue_count(wl) == 0) {
mutex_unlock(&wl->mutex);
goto out;
}

wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH);

while (!time_after(jiffies, timeout)) {
mutex_lock(&wl->mutex);
wl1271_debug(DEBUG_MAC80211, "flushing tx buffer: %d %d",
wl->tx_frames_cnt,
wl1271_tx_total_queue_count(wl));

/* force Tx and give the driver some time to flush data */
mutex_unlock(&wl->mutex);
if (wl1271_tx_total_queue_count(wl))
wl1271_tx_work(&wl->tx_work);
msleep(20);
mutex_lock(&wl->mutex);

if ((wl->tx_frames_cnt == 0) &&
(wl1271_tx_total_queue_count(wl) == 0)) {
mutex_unlock(&wl->mutex);
wl1271_debug(DEBUG_MAC80211, "tx flush took %d ms",
jiffies_to_msecs(jiffies - start_time));
goto out;
goto out_wake;
}
mutex_unlock(&wl->mutex);
msleep(1);
}

wl1271_warning("Unable to flush all TX buffers, "
"timed out (timeout %d ms",
WL1271_TX_FLUSH_TIMEOUT / 1000);

/* forcibly flush all Tx buffers on our queues */
mutex_lock(&wl->mutex);
for (i = 0; i < WL12XX_MAX_LINKS; i++)
wl1271_tx_reset_link_queues(wl, i);
mutex_unlock(&wl->mutex);

out:
out_wake:
wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH);
mutex_unlock(&wl->mutex);
out:
mutex_unlock(&wl->flush_mutex);
}
EXPORT_SYMBOL_GPL(wl1271_tx_flush);
Expand Down

0 comments on commit f83e541

Please sign in to comment.