mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 23:22:31 +02:00
net: ipa: always use transaction IDs instead of lists
In gsi_channel_trans_complete(), use the completed and pending IDs to determine whether there are any transactions in completed state. Similarly, in gsi_channel_trans_cancel_pending(), use the pending and committed IDs to mark pending transactions cancelled. Rearrange the logic a bit there for a simpler result. This removes the only user of list_last_entry_or_null(), so get rid of that macro. Remove the temporary warnings added by the previous commit. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6fff926141
commit
0c126ec3dd
|
|
@ -16,20 +16,6 @@ struct gsi_channel;
|
|||
|
||||
#define GSI_RING_ELEMENT_SIZE 16 /* bytes; must be a power of 2 */
|
||||
|
||||
/**
|
||||
* list_last_entry_or_null - get the last element from a list
|
||||
* @ptr: the list head to take the element from.
|
||||
* @type: the type of the struct this is embedded in.
|
||||
* @member: the name of the list_head within the struct.
|
||||
*
|
||||
* Note that if the list is empty, it returns NULL.
|
||||
*/
|
||||
#define list_last_entry_or_null(ptr, type, member) ({ \
|
||||
struct list_head *head__ = (ptr); \
|
||||
struct list_head *pos__ = READ_ONCE(head__->prev); \
|
||||
pos__ != head__ ? list_entry(pos__, type, member) : NULL; \
|
||||
})
|
||||
|
||||
/**
|
||||
* gsi_trans_move_complete() - Mark a GSI transaction completed
|
||||
* @trans: Transaction to commit
|
||||
|
|
|
|||
|
|
@ -239,22 +239,11 @@ struct gsi_trans *gsi_channel_trans_complete(struct gsi_channel *channel)
|
|||
{
|
||||
struct gsi_trans_info *trans_info = &channel->trans_info;
|
||||
u16 trans_id = trans_info->completed_id;
|
||||
struct gsi_trans *trans;
|
||||
|
||||
trans = list_first_entry_or_null(&trans_info->complete,
|
||||
struct gsi_trans, links);
|
||||
|
||||
if (!trans) {
|
||||
WARN_ON(trans_id != trans_info->pending_id);
|
||||
if (trans_id == trans_info->pending_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!WARN_ON(trans_id == trans_info->pending_id)) {
|
||||
trans_id %= channel->tre_count;
|
||||
WARN_ON(trans != &trans_info->trans[trans_id]);
|
||||
}
|
||||
|
||||
return trans;
|
||||
return &trans_info->trans[trans_id %= channel->tre_count];
|
||||
}
|
||||
|
||||
/* Move a transaction from the allocated list to the committed list */
|
||||
|
|
@ -705,47 +694,32 @@ void gsi_trans_complete(struct gsi_trans *trans)
|
|||
void gsi_channel_trans_cancel_pending(struct gsi_channel *channel)
|
||||
{
|
||||
struct gsi_trans_info *trans_info = &channel->trans_info;
|
||||
struct gsi_trans *trans;
|
||||
struct gsi_trans *first;
|
||||
struct gsi_trans *last;
|
||||
bool cancelled;
|
||||
u16 trans_id = trans_info->pending_id;
|
||||
|
||||
/* channel->gsi->mutex is held by caller */
|
||||
spin_lock_bh(&trans_info->spinlock);
|
||||
|
||||
cancelled = !list_empty(&trans_info->pending);
|
||||
list_for_each_entry(trans, &trans_info->pending, links)
|
||||
trans->cancelled = true;
|
||||
|
||||
list_splice_tail_init(&trans_info->pending, &trans_info->complete);
|
||||
|
||||
first = list_first_entry_or_null(&trans_info->complete,
|
||||
struct gsi_trans, links);
|
||||
last = list_last_entry_or_null(&trans_info->complete,
|
||||
struct gsi_trans, links);
|
||||
|
||||
spin_unlock_bh(&trans_info->spinlock);
|
||||
|
||||
/* All pending transactions are now completed */
|
||||
WARN_ON(cancelled != (trans_info->pending_id !=
|
||||
trans_info->committed_id));
|
||||
/* If there are no pending transactions, we're done */
|
||||
if (trans_id == trans_info->committed_id)
|
||||
return;
|
||||
|
||||
/* Mark all pending transactions cancelled */
|
||||
do {
|
||||
struct gsi_trans *trans;
|
||||
|
||||
trans = &trans_info->trans[trans_id % channel->tre_count];
|
||||
trans->cancelled = true;
|
||||
} while (++trans_id != trans_info->committed_id);
|
||||
|
||||
/* All pending transactions are now completed */
|
||||
trans_info->pending_id = trans_info->committed_id;
|
||||
|
||||
/* Schedule NAPI polling to complete the cancelled transactions */
|
||||
if (cancelled) {
|
||||
u16 trans_id;
|
||||
|
||||
napi_schedule(&channel->napi);
|
||||
|
||||
trans_id = trans_info->completed_id;
|
||||
trans = &trans_info->trans[trans_id % channel->tre_count];
|
||||
WARN_ON(trans != first);
|
||||
|
||||
trans_id = trans_info->pending_id - 1;
|
||||
trans = &trans_info->trans[trans_id % channel->tre_count];
|
||||
WARN_ON(trans != last);
|
||||
}
|
||||
napi_schedule(&channel->napi);
|
||||
}
|
||||
|
||||
/* Issue a command to read a single byte from a channel */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user