Commit 306a2782 authored by Ben Hutchings's avatar Ben Hutchings

sfc: Separate out queue-empty check from efx_nic_may_push_tx_desc()

Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
parent 183233be
...@@ -71,6 +71,26 @@ efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index) ...@@ -71,6 +71,26 @@ efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
return ((efx_qword_t *) (tx_queue->txd.buf.addr)) + index; return ((efx_qword_t *) (tx_queue->txd.buf.addr)) + index;
} }
/* Report whether the NIC considers this TX queue empty, given the
* write_count used for the last doorbell push. May return false
* negative.
*/
static inline bool __efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue,
unsigned int write_count)
{
unsigned int empty_read_count = ACCESS_ONCE(tx_queue->empty_read_count);
if (empty_read_count == 0)
return false;
return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0;
}
static inline bool efx_nic_tx_is_empty(struct efx_tx_queue *tx_queue)
{
return __efx_nic_tx_is_empty(tx_queue, tx_queue->write_count);
}
/* Decide whether to push a TX descriptor to the NIC vs merely writing /* Decide whether to push a TX descriptor to the NIC vs merely writing
* the doorbell. This can reduce latency when we are adding a single * the doorbell. This can reduce latency when we are adding a single
* descriptor to an empty queue, but is otherwise pointless. Further, * descriptor to an empty queue, but is otherwise pointless. Further,
...@@ -80,14 +100,10 @@ efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index) ...@@ -80,14 +100,10 @@ efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
static inline bool efx_nic_may_push_tx_desc(struct efx_tx_queue *tx_queue, static inline bool efx_nic_may_push_tx_desc(struct efx_tx_queue *tx_queue,
unsigned int write_count) unsigned int write_count)
{ {
unsigned empty_read_count = ACCESS_ONCE(tx_queue->empty_read_count); bool was_empty = __efx_nic_tx_is_empty(tx_queue, write_count);
if (empty_read_count == 0)
return false;
tx_queue->empty_read_count = 0; tx_queue->empty_read_count = 0;
return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0 return was_empty && tx_queue->write_count - write_count == 1;
&& tx_queue->write_count - write_count == 1;
} }
/* Returns a pointer to the specified descriptor in the RX descriptor queue */ /* Returns a pointer to the specified descriptor in the RX descriptor queue */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment