sfc: replace asynchronous filter operations
Instead of having an efx->type->filter_rfs_insert() method, just use workitems with a worker function that calls efx->type->filter_insert(). The only user of this is efx_filter_rfs(), which now queues a call to efx_filter_rfs_work(). Similarly, efx_filter_rfs_expire() is now a worker function called on a new channel->filter_work work_struct, so the method efx->type->filter_rfs_expire_one() is no longer called in atomic context. We also add a new mutex efx->rps_mutex to protect the RPS state (efx-> rps_expire_channel, efx->rps_expire_index, and channel->rps_flow_id) so that the taking of efx->filter_lock can be moved to efx->type->filter_rfs_expire_one(). Thus, all filter table functions are now called in a sleepable context, allowing them to use sleeping locks in a future patch. Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committad av
David S. Miller

förälder
c709002c23
incheckning
3af0f34290
@@ -430,6 +430,7 @@ enum efx_sync_events_state {
|
||||
* @event_test_cpu: Last CPU to handle interrupt or test event for this channel
|
||||
* @irq_count: Number of IRQs since last adaptive moderation decision
|
||||
* @irq_mod_score: IRQ moderation score
|
||||
* @filter_work: Work item for efx_filter_rfs_expire()
|
||||
* @rps_flow_id: Flow IDs of filters allocated for accelerated RFS,
|
||||
* indexed by filter ID
|
||||
* @n_rx_tobe_disc: Count of RX_TOBE_DISC errors
|
||||
@@ -475,6 +476,7 @@ struct efx_channel {
|
||||
unsigned int irq_mod_score;
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
unsigned int rfs_filters_added;
|
||||
struct work_struct filter_work;
|
||||
#define RPS_FLOW_ID_INVALID 0xFFFFFFFF
|
||||
u32 *rps_flow_id;
|
||||
#endif
|
||||
@@ -844,6 +846,7 @@ struct efx_rss_context {
|
||||
* @filter_sem: Filter table rw_semaphore, for freeing the table
|
||||
* @filter_lock: Filter table lock, for mere content changes
|
||||
* @filter_state: Architecture-dependent filter table state
|
||||
* @rps_mutex: Protects RPS state of all channels
|
||||
* @rps_expire_channel: Next channel to check for expiry
|
||||
* @rps_expire_index: Next index to check for expiry in
|
||||
* @rps_expire_channel's @rps_flow_id
|
||||
@@ -998,6 +1001,7 @@ struct efx_nic {
|
||||
spinlock_t filter_lock;
|
||||
void *filter_state;
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
struct mutex rps_mutex;
|
||||
unsigned int rps_expire_channel;
|
||||
unsigned int rps_expire_index;
|
||||
#endif
|
||||
@@ -1152,10 +1156,6 @@ struct efx_udp_tunnel {
|
||||
* @filter_count_rx_used: Get the number of filters in use at a given priority
|
||||
* @filter_get_rx_id_limit: Get maximum value of a filter id, plus 1
|
||||
* @filter_get_rx_ids: Get list of RX filters at a given priority
|
||||
* @filter_rfs_insert: Add or replace a filter for RFS. This must be
|
||||
* atomic. The hardware change may be asynchronous but should
|
||||
* not be delayed for long. It may fail if this can't be done
|
||||
* atomically.
|
||||
* @filter_rfs_expire_one: Consider expiring a filter inserted for RFS.
|
||||
* This must check whether the specified table entry is used by RFS
|
||||
* and that rps_may_expire_flow() returns true for it.
|
||||
@@ -1306,8 +1306,6 @@ struct efx_nic_type {
|
||||
enum efx_filter_priority priority,
|
||||
u32 *buf, u32 size);
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
s32 (*filter_rfs_insert)(struct efx_nic *efx,
|
||||
struct efx_filter_spec *spec);
|
||||
bool (*filter_rfs_expire_one)(struct efx_nic *efx, u32 flow_id,
|
||||
unsigned int index);
|
||||
#endif
|
||||
|
Referens i nytt ärende
Block a user