sfc: Refactor Falcon-arch search limit reset
Currently every call to efx_farch_filter_table_clear_entry() is shortly followed by a conditional reset of the table limits. The new limits (0) are not pushed to hardware until the next filter insertion. Move both the reset and the hardware reconfiguration into efx_farch_filter_table_clear_entry(), and add an explanatory comment. Also, make consistent use of the term 'search limit' for the maximum number of probes the NIC must make when searching for a filter of a particular type. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
This commit is contained in:
Родитель
6d661cec79
Коммит
9a0a943321
|
@ -22,7 +22,7 @@
|
||||||
#define EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD 3
|
#define EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD 3
|
||||||
#define EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL 1
|
#define EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL 1
|
||||||
|
|
||||||
/* Hard maximum hop limit. Hardware will time-out beyond 200-something.
|
/* Hard maximum search limit. Hardware will time-out beyond 200-something.
|
||||||
* We also need to avoid infinite loops in efx_farch_filter_search() when the
|
* We also need to avoid infinite loops in efx_farch_filter_search() when the
|
||||||
* table is full.
|
* table is full.
|
||||||
*/
|
*/
|
||||||
|
@ -74,7 +74,7 @@ struct efx_farch_filter_table {
|
||||||
unsigned used; /* number currently used */
|
unsigned used; /* number currently used */
|
||||||
unsigned long *used_bitmap;
|
unsigned long *used_bitmap;
|
||||||
struct efx_farch_filter_spec *spec;
|
struct efx_farch_filter_spec *spec;
|
||||||
unsigned search_depth[EFX_FARCH_FILTER_TYPE_COUNT];
|
unsigned search_limit[EFX_FARCH_FILTER_TYPE_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct efx_farch_filter_state {
|
struct efx_farch_filter_state {
|
||||||
|
@ -129,12 +129,6 @@ efx_farch_filter_spec_table_id(const struct efx_farch_filter_spec *spec)
|
||||||
return (spec->type >> 2) + ((spec->flags & EFX_FILTER_FLAG_TX) ? 2 : 0);
|
return (spec->type >> 2) + ((spec->flags & EFX_FILTER_FLAG_TX) ? 2 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
efx_farch_filter_table_reset_search_depth(struct efx_farch_filter_table *table)
|
|
||||||
{
|
|
||||||
memset(table->search_depth, 0, sizeof(table->search_depth));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void efx_farch_filter_push_rx_config(struct efx_nic *efx)
|
static void efx_farch_filter_push_rx_config(struct efx_nic *efx)
|
||||||
{
|
{
|
||||||
struct efx_farch_filter_state *state = efx->filter_state;
|
struct efx_farch_filter_state *state = efx->filter_state;
|
||||||
|
@ -145,27 +139,27 @@ static void efx_farch_filter_push_rx_config(struct efx_nic *efx)
|
||||||
|
|
||||||
table = &state->table[EFX_FARCH_FILTER_TABLE_RX_IP];
|
table = &state->table[EFX_FARCH_FILTER_TABLE_RX_IP];
|
||||||
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT,
|
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT,
|
||||||
table->search_depth[EFX_FARCH_FILTER_TCP_FULL] +
|
table->search_limit[EFX_FARCH_FILTER_TCP_FULL] +
|
||||||
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
|
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
|
||||||
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT,
|
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT,
|
||||||
table->search_depth[EFX_FARCH_FILTER_TCP_WILD] +
|
table->search_limit[EFX_FARCH_FILTER_TCP_WILD] +
|
||||||
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
|
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
|
||||||
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT,
|
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT,
|
||||||
table->search_depth[EFX_FARCH_FILTER_UDP_FULL] +
|
table->search_limit[EFX_FARCH_FILTER_UDP_FULL] +
|
||||||
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
|
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
|
||||||
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT,
|
EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT,
|
||||||
table->search_depth[EFX_FARCH_FILTER_UDP_WILD] +
|
table->search_limit[EFX_FARCH_FILTER_UDP_WILD] +
|
||||||
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
|
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
|
||||||
|
|
||||||
table = &state->table[EFX_FARCH_FILTER_TABLE_RX_MAC];
|
table = &state->table[EFX_FARCH_FILTER_TABLE_RX_MAC];
|
||||||
if (table->size) {
|
if (table->size) {
|
||||||
EFX_SET_OWORD_FIELD(
|
EFX_SET_OWORD_FIELD(
|
||||||
filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,
|
filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,
|
||||||
table->search_depth[EFX_FARCH_FILTER_MAC_FULL] +
|
table->search_limit[EFX_FARCH_FILTER_MAC_FULL] +
|
||||||
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
|
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
|
||||||
EFX_SET_OWORD_FIELD(
|
EFX_SET_OWORD_FIELD(
|
||||||
filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,
|
filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,
|
||||||
table->search_depth[EFX_FARCH_FILTER_MAC_WILD] +
|
table->search_limit[EFX_FARCH_FILTER_MAC_WILD] +
|
||||||
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
|
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,11 +215,11 @@ static void efx_farch_filter_push_tx_limits(struct efx_nic *efx)
|
||||||
if (table->size) {
|
if (table->size) {
|
||||||
EFX_SET_OWORD_FIELD(
|
EFX_SET_OWORD_FIELD(
|
||||||
tx_cfg, FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE,
|
tx_cfg, FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE,
|
||||||
table->search_depth[EFX_FARCH_FILTER_MAC_FULL] +
|
table->search_limit[EFX_FARCH_FILTER_MAC_FULL] +
|
||||||
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
|
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_FULL);
|
||||||
EFX_SET_OWORD_FIELD(
|
EFX_SET_OWORD_FIELD(
|
||||||
tx_cfg, FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE,
|
tx_cfg, FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE,
|
||||||
table->search_depth[EFX_FARCH_FILTER_MAC_WILD] +
|
table->search_limit[EFX_FARCH_FILTER_MAC_WILD] +
|
||||||
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
|
EFX_FARCH_FILTER_CTL_SRCH_FUDGE_WILD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,8 +627,8 @@ s32 efx_filter_insert_filter(struct efx_nic *efx,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
netif_vdbg(efx, hw, efx->net_dev,
|
netif_vdbg(efx, hw, efx->net_dev,
|
||||||
"%s: type %d search_depth=%d", __func__, spec.type,
|
"%s: type %d search_limit=%d", __func__, spec.type,
|
||||||
table->search_depth[spec.type]);
|
table->search_limit[spec.type]);
|
||||||
|
|
||||||
if (table->id == EFX_FARCH_FILTER_TABLE_RX_DEF) {
|
if (table->id == EFX_FARCH_FILTER_TABLE_RX_DEF) {
|
||||||
/* One filter spec per type */
|
/* One filter spec per type */
|
||||||
|
@ -664,7 +658,7 @@ s32 efx_filter_insert_filter(struct efx_nic *efx,
|
||||||
u32 key = efx_farch_filter_build(&filter, &spec);
|
u32 key = efx_farch_filter_build(&filter, &spec);
|
||||||
unsigned int hash = efx_farch_filter_hash(key);
|
unsigned int hash = efx_farch_filter_hash(key);
|
||||||
unsigned int incr = efx_farch_filter_increment(key);
|
unsigned int incr = efx_farch_filter_increment(key);
|
||||||
unsigned int max_rep_depth = table->search_depth[spec.type];
|
unsigned int max_rep_depth = table->search_limit[spec.type];
|
||||||
unsigned int max_ins_depth =
|
unsigned int max_ins_depth =
|
||||||
spec.priority <= EFX_FILTER_PRI_HINT ?
|
spec.priority <= EFX_FILTER_PRI_HINT ?
|
||||||
EFX_FARCH_FILTER_CTL_SRCH_HINT_MAX :
|
EFX_FARCH_FILTER_CTL_SRCH_HINT_MAX :
|
||||||
|
@ -732,8 +726,8 @@ s32 efx_filter_insert_filter(struct efx_nic *efx,
|
||||||
if (table->id == EFX_FARCH_FILTER_TABLE_RX_DEF) {
|
if (table->id == EFX_FARCH_FILTER_TABLE_RX_DEF) {
|
||||||
efx_farch_filter_push_rx_config(efx);
|
efx_farch_filter_push_rx_config(efx);
|
||||||
} else {
|
} else {
|
||||||
if (table->search_depth[spec.type] < depth) {
|
if (table->search_limit[spec.type] < depth) {
|
||||||
table->search_depth[spec.type] = depth;
|
table->search_limit[spec.type] = depth;
|
||||||
if (spec.flags & EFX_FILTER_FLAG_TX)
|
if (spec.flags & EFX_FILTER_FLAG_TX)
|
||||||
efx_farch_filter_push_tx_limits(efx);
|
efx_farch_filter_push_tx_limits(efx);
|
||||||
else
|
else
|
||||||
|
@ -779,6 +773,21 @@ efx_farch_filter_table_clear_entry(struct efx_nic *efx,
|
||||||
|
|
||||||
efx_writeo(efx, &filter,
|
efx_writeo(efx, &filter,
|
||||||
table->offset + table->step * filter_idx);
|
table->offset + table->step * filter_idx);
|
||||||
|
|
||||||
|
/* If this filter required a greater search depth than
|
||||||
|
* any other, the search limit for its type can now be
|
||||||
|
* decreased. However, it is hard to determine that
|
||||||
|
* unless the table has become completely empty - in
|
||||||
|
* which case, all its search limits can be set to 0.
|
||||||
|
*/
|
||||||
|
if (unlikely(table->used == 0)) {
|
||||||
|
memset(table->search_limit, 0,
|
||||||
|
sizeof(table->search_limit));
|
||||||
|
if (table->id == EFX_FARCH_FILTER_TABLE_TX_MAC)
|
||||||
|
efx_farch_filter_push_tx_limits(efx);
|
||||||
|
else
|
||||||
|
efx_farch_filter_push_rx_config(efx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,8 +826,6 @@ int efx_filter_remove_id_safe(struct efx_nic *efx,
|
||||||
if (test_bit(filter_idx, table->used_bitmap) &&
|
if (test_bit(filter_idx, table->used_bitmap) &&
|
||||||
spec->priority == priority) {
|
spec->priority == priority) {
|
||||||
efx_farch_filter_table_clear_entry(efx, table, filter_idx);
|
efx_farch_filter_table_clear_entry(efx, table, filter_idx);
|
||||||
if (table->used == 0)
|
|
||||||
efx_farch_filter_table_reset_search_depth(table);
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
rc = -ENOENT;
|
rc = -ENOENT;
|
||||||
|
@ -885,14 +892,10 @@ efx_farch_filter_table_clear(struct efx_nic *efx,
|
||||||
unsigned int filter_idx;
|
unsigned int filter_idx;
|
||||||
|
|
||||||
spin_lock_bh(&efx->filter_lock);
|
spin_lock_bh(&efx->filter_lock);
|
||||||
|
|
||||||
for (filter_idx = 0; filter_idx < table->size; ++filter_idx)
|
for (filter_idx = 0; filter_idx < table->size; ++filter_idx)
|
||||||
if (table->spec[filter_idx].priority <= priority)
|
if (table->spec[filter_idx].priority <= priority)
|
||||||
efx_farch_filter_table_clear_entry(efx, table,
|
efx_farch_filter_table_clear_entry(efx, table,
|
||||||
filter_idx);
|
filter_idx);
|
||||||
if (table->used == 0)
|
|
||||||
efx_farch_filter_table_reset_search_depth(table);
|
|
||||||
|
|
||||||
spin_unlock_bh(&efx->filter_lock);
|
spin_unlock_bh(&efx->filter_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1233,8 +1236,6 @@ bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned quota)
|
||||||
}
|
}
|
||||||
|
|
||||||
efx->rps_expire_index = stop;
|
efx->rps_expire_index = stop;
|
||||||
if (table->used == 0)
|
|
||||||
efx_farch_filter_table_reset_search_depth(table);
|
|
||||||
|
|
||||||
spin_unlock_bh(&efx->filter_lock);
|
spin_unlock_bh(&efx->filter_lock);
|
||||||
return true;
|
return true;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче