mirror of https://gitee.com/openkylin/linux.git
nfp: flower: handle merge hint messages
If a merge hint is received containing 2 flows that are matched via an implicit recirculation (sending to and matching on an internal port), fw reports that the flows (called sub_flows) may be able to be combined to a single flow. Add infastructure to accept and process merge hint messages. The actual merging of the flows is left as a stub call. Signed-off-by: John Hurley <john.hurley@netronome.com> Signed-off-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
cf4172d575
commit
dbc2d68edc
|
@ -204,6 +204,50 @@ nfp_flower_cmsg_portreify_rx(struct nfp_app *app, struct sk_buff *skb)
|
|||
wake_up(&priv->reify_wait_queue);
|
||||
}
|
||||
|
||||
static void
|
||||
nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb)
|
||||
{
|
||||
unsigned int msg_len = nfp_flower_cmsg_get_data_len(skb);
|
||||
struct nfp_flower_cmsg_merge_hint *msg;
|
||||
struct nfp_fl_payload *sub_flows[2];
|
||||
int err, i, flow_cnt;
|
||||
|
||||
msg = nfp_flower_cmsg_get_data(skb);
|
||||
/* msg->count starts at 0 and always assumes at least 1 entry. */
|
||||
flow_cnt = msg->count + 1;
|
||||
|
||||
if (msg_len < struct_size(msg, flow, flow_cnt)) {
|
||||
nfp_flower_cmsg_warn(app, "Merge hint ctrl msg too short - %d bytes but expect %ld\n",
|
||||
msg_len, struct_size(msg, flow, flow_cnt));
|
||||
return;
|
||||
}
|
||||
|
||||
if (flow_cnt != 2) {
|
||||
nfp_flower_cmsg_warn(app, "Merge hint contains %d flows - two are expected\n",
|
||||
flow_cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
rtnl_lock();
|
||||
for (i = 0; i < flow_cnt; i++) {
|
||||
u32 ctx = be32_to_cpu(msg->flow[i].host_ctx);
|
||||
|
||||
sub_flows[i] = nfp_flower_get_fl_payload_from_ctx(app, ctx);
|
||||
if (!sub_flows[i]) {
|
||||
nfp_flower_cmsg_warn(app, "Invalid flow in merge hint\n");
|
||||
goto err_rtnl_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
err = nfp_flower_merge_offloaded_flows(app, sub_flows[0], sub_flows[1]);
|
||||
/* Only warn on memory fail. Hint veto will not break functionality. */
|
||||
if (err == -ENOMEM)
|
||||
nfp_flower_cmsg_warn(app, "Flow merge memory fail.\n");
|
||||
|
||||
err_rtnl_unlock:
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
static void
|
||||
nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
|
||||
{
|
||||
|
@ -223,8 +267,10 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
|
|||
nfp_flower_cmsg_portmod_rx(app, skb);
|
||||
break;
|
||||
case NFP_FLOWER_CMSG_TYPE_MERGE_HINT:
|
||||
if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MERGE)
|
||||
if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MERGE) {
|
||||
nfp_flower_cmsg_merge_hint_rx(app, skb);
|
||||
break;
|
||||
}
|
||||
goto err_default;
|
||||
case NFP_FLOWER_CMSG_TYPE_NO_NEIGH:
|
||||
nfp_tunnel_request_route(app, skb);
|
||||
|
|
|
@ -452,6 +452,16 @@ struct nfp_flower_cmsg_portreify {
|
|||
|
||||
#define NFP_FLOWER_CMSG_PORTREIFY_INFO_EXIST BIT(0)
|
||||
|
||||
/* NFP_FLOWER_CMSG_TYPE_FLOW_MERGE_HINT */
|
||||
struct nfp_flower_cmsg_merge_hint {
|
||||
u8 reserved[3];
|
||||
u8 count;
|
||||
struct {
|
||||
__be32 host_ctx;
|
||||
__be64 host_cookie;
|
||||
} __packed flow[0];
|
||||
};
|
||||
|
||||
enum nfp_flower_cmsg_port_type {
|
||||
NFP_FLOWER_CMSG_PORT_TYPE_UNSPEC = 0x0,
|
||||
NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT = 0x1,
|
||||
|
|
|
@ -285,6 +285,9 @@ void nfp_flower_metadata_cleanup(struct nfp_app *app);
|
|||
|
||||
int nfp_flower_setup_tc(struct nfp_app *app, struct net_device *netdev,
|
||||
enum tc_setup_type type, void *type_data);
|
||||
int nfp_flower_merge_offloaded_flows(struct nfp_app *app,
|
||||
struct nfp_fl_payload *sub_flow1,
|
||||
struct nfp_fl_payload *sub_flow2);
|
||||
int nfp_flower_compile_flow_match(struct nfp_app *app,
|
||||
struct tc_cls_flower_offload *flow,
|
||||
struct nfp_fl_key_ls *key_ls,
|
||||
|
|
|
@ -388,6 +388,24 @@ nfp_flower_allocate_new(struct nfp_fl_key_ls *key_layer)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfp_flower_merge_offloaded_flows() - Merge 2 existing flows to single flow.
|
||||
* @app: Pointer to the APP handle
|
||||
* @sub_flow1: Initial flow matched to produce merge hint
|
||||
* @sub_flow2: Post recirculation flow matched in merge hint
|
||||
*
|
||||
* Combines 2 flows (if valid) to a single flow, removing the initial from hw
|
||||
* and offloading the new, merged flow.
|
||||
*
|
||||
* Return: negative value on error, 0 in success.
|
||||
*/
|
||||
int nfp_flower_merge_offloaded_flows(struct nfp_app *app,
|
||||
struct nfp_fl_payload *sub_flow1,
|
||||
struct nfp_fl_payload *sub_flow2)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfp_flower_add_offload() - Adds a new flow to hardware.
|
||||
* @app: Pointer to the APP handle
|
||||
|
|
Loading…
Reference in New Issue