Commit 467322e2 authored by Pieter Jansen van Vuuren's avatar Pieter Jansen van Vuuren Committed by David S. Miller

nfp: flower: support multiple memory units for filter offloads

Adds support for multiple memory units which are used for filter
offloads. Each filter is assigned a stats id, the MSBs of the id are
used to determine which memory unit the filter should be offloaded
to. The number of available memory units that could be used for filter
offload is obtained from HW. A simple round robin technique is used to
allocate and distribute the ids across memory units.
Signed-off-by: default avatarPieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 96439889
...@@ -474,8 +474,8 @@ static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn) ...@@ -474,8 +474,8 @@ static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn)
static int nfp_flower_init(struct nfp_app *app) static int nfp_flower_init(struct nfp_app *app)
{ {
u64 version, features, ctx_count, num_mems;
const struct nfp_pf *pf = app->pf; const struct nfp_pf *pf = app->pf;
u64 version, features, ctx_count;
struct nfp_flower_priv *app_priv; struct nfp_flower_priv *app_priv;
int err; int err;
...@@ -500,6 +500,23 @@ static int nfp_flower_init(struct nfp_app *app) ...@@ -500,6 +500,23 @@ static int nfp_flower_init(struct nfp_app *app)
return err; return err;
} }
num_mems = nfp_rtsym_read_le(app->pf->rtbl, "CONFIG_FC_HOST_CTX_SPLIT",
&err);
if (err) {
nfp_warn(app->cpp,
"FlowerNIC: unsupported host context memory: %d\n",
err);
err = 0;
num_mems = 1;
}
if (!FIELD_FIT(NFP_FL_STAT_ID_MU_NUM, num_mems) || !num_mems) {
nfp_warn(app->cpp,
"FlowerNIC: invalid host context memory: %llu\n",
num_mems);
return -EINVAL;
}
ctx_count = nfp_rtsym_read_le(app->pf->rtbl, "CONFIG_FC_HOST_CTX_COUNT", ctx_count = nfp_rtsym_read_le(app->pf->rtbl, "CONFIG_FC_HOST_CTX_COUNT",
&err); &err);
if (err) { if (err) {
...@@ -520,6 +537,8 @@ static int nfp_flower_init(struct nfp_app *app) ...@@ -520,6 +537,8 @@ static int nfp_flower_init(struct nfp_app *app)
if (!app_priv) if (!app_priv)
return -ENOMEM; return -ENOMEM;
app_priv->total_mem_units = num_mems;
app_priv->active_mem_unit = 0;
app_priv->stats_ring_size = roundup_pow_of_two(ctx_count); app_priv->stats_ring_size = roundup_pow_of_two(ctx_count);
app->priv = app_priv; app->priv = app_priv;
app_priv->app = app; app_priv->app = app;
...@@ -531,7 +550,7 @@ static int nfp_flower_init(struct nfp_app *app) ...@@ -531,7 +550,7 @@ static int nfp_flower_init(struct nfp_app *app)
init_waitqueue_head(&app_priv->mtu_conf.wait_q); init_waitqueue_head(&app_priv->mtu_conf.wait_q);
spin_lock_init(&app_priv->mtu_conf.lock); spin_lock_init(&app_priv->mtu_conf.lock);
err = nfp_flower_metadata_init(app, ctx_count); err = nfp_flower_metadata_init(app, ctx_count, num_mems);
if (err) if (err)
goto err_free_app_priv; goto err_free_app_priv;
......
...@@ -20,6 +20,9 @@ struct nfp_fl_pre_lag; ...@@ -20,6 +20,9 @@ struct nfp_fl_pre_lag;
struct net_device; struct net_device;
struct nfp_app; struct nfp_app;
#define NFP_FL_STAT_ID_MU_NUM GENMASK(31, 22)
#define NFP_FL_STAT_ID_STAT GENMASK(21, 0)
#define NFP_FL_STATS_ELEM_RS FIELD_SIZEOF(struct nfp_fl_stats_id, \ #define NFP_FL_STATS_ELEM_RS FIELD_SIZEOF(struct nfp_fl_stats_id, \
init_unalloc) init_unalloc)
#define NFP_FLOWER_MASK_ENTRY_RS 256 #define NFP_FLOWER_MASK_ENTRY_RS 256
...@@ -130,6 +133,8 @@ struct nfp_fl_lag { ...@@ -130,6 +133,8 @@ struct nfp_fl_lag {
* @mtu_conf: Configuration of repr MTU value * @mtu_conf: Configuration of repr MTU value
* @nfp_lag: Link aggregation data block * @nfp_lag: Link aggregation data block
* @indr_block_cb_priv: List of priv data passed to indirect block cbs * @indr_block_cb_priv: List of priv data passed to indirect block cbs
* @active_mem_unit: Current active memory unit for flower rules
* @total_mem_units: Total number of available memory units for flower rules
*/ */
struct nfp_flower_priv { struct nfp_flower_priv {
struct nfp_app *app; struct nfp_app *app;
...@@ -163,6 +168,8 @@ struct nfp_flower_priv { ...@@ -163,6 +168,8 @@ struct nfp_flower_priv {
struct nfp_mtu_conf mtu_conf; struct nfp_mtu_conf mtu_conf;
struct nfp_fl_lag nfp_lag; struct nfp_fl_lag nfp_lag;
struct list_head indr_block_cb_priv; struct list_head indr_block_cb_priv;
unsigned int active_mem_unit;
unsigned int total_mem_units;
}; };
/** /**
...@@ -217,7 +224,8 @@ struct nfp_fl_stats_frame { ...@@ -217,7 +224,8 @@ struct nfp_fl_stats_frame {
__be64 stats_cookie; __be64 stats_cookie;
}; };
int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count); int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count,
unsigned int host_ctx_split);
void nfp_flower_metadata_cleanup(struct nfp_app *app); void nfp_flower_metadata_cleanup(struct nfp_app *app);
int nfp_flower_setup_tc(struct nfp_app *app, struct net_device *netdev, int nfp_flower_setup_tc(struct nfp_app *app, struct net_device *netdev,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <linux/hash.h> #include <linux/hash.h>
#include <linux/hashtable.h> #include <linux/hashtable.h>
#include <linux/jhash.h> #include <linux/jhash.h>
#include <linux/math64.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
...@@ -52,8 +53,17 @@ static int nfp_get_stats_entry(struct nfp_app *app, u32 *stats_context_id) ...@@ -52,8 +53,17 @@ static int nfp_get_stats_entry(struct nfp_app *app, u32 *stats_context_id)
freed_stats_id = priv->stats_ring_size; freed_stats_id = priv->stats_ring_size;
/* Check for unallocated entries first. */ /* Check for unallocated entries first. */
if (priv->stats_ids.init_unalloc > 0) { if (priv->stats_ids.init_unalloc > 0) {
*stats_context_id = priv->stats_ids.init_unalloc - 1; if (priv->active_mem_unit == priv->total_mem_units) {
priv->stats_ids.init_unalloc--; priv->stats_ids.init_unalloc--;
priv->active_mem_unit = 0;
}
*stats_context_id =
FIELD_PREP(NFP_FL_STAT_ID_STAT,
priv->stats_ids.init_unalloc - 1) |
FIELD_PREP(NFP_FL_STAT_ID_MU_NUM,
priv->active_mem_unit);
priv->active_mem_unit++;
return 0; return 0;
} }
...@@ -381,10 +391,11 @@ const struct rhashtable_params nfp_flower_table_params = { ...@@ -381,10 +391,11 @@ const struct rhashtable_params nfp_flower_table_params = {
.automatic_shrinking = true, .automatic_shrinking = true,
}; };
int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count) int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count,
unsigned int host_num_mems)
{ {
struct nfp_flower_priv *priv = app->priv; struct nfp_flower_priv *priv = app->priv;
int err; int err, stats_size;
hash_init(priv->mask_table); hash_init(priv->mask_table);
...@@ -417,10 +428,12 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count) ...@@ -417,10 +428,12 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count)
if (!priv->stats_ids.free_list.buf) if (!priv->stats_ids.free_list.buf)
goto err_free_last_used; goto err_free_last_used;
priv->stats_ids.init_unalloc = host_ctx_count; priv->stats_ids.init_unalloc = div_u64(host_ctx_count, host_num_mems);
priv->stats = kvmalloc_array(priv->stats_ring_size, stats_size = FIELD_PREP(NFP_FL_STAT_ID_STAT, host_ctx_count) |
sizeof(struct nfp_fl_stats), GFP_KERNEL); FIELD_PREP(NFP_FL_STAT_ID_MU_NUM, host_num_mems - 1);
priv->stats = kvmalloc_array(stats_size, sizeof(struct nfp_fl_stats),
GFP_KERNEL);
if (!priv->stats) if (!priv->stats)
goto err_free_ring_buf; goto err_free_ring_buf;
......
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