Hi Wei, On Tue, Dec 20, 2016 at 07:32:29AM +0000, Zhao1, Wei wrote: > Hi, Adrien > > > -----Original Message----- > > From: dev [mailto:dev-boun...@dpdk.org] On Behalf Of Adrien Mazarguil > > Sent: Tuesday, December 20, 2016 1:49 AM > > To: dev@dpdk.org > > Subject: [dpdk-dev] [PATCH v3 10/25] app/testpmd: add flow flush > > command > > > > Syntax: > > > > flow flush {port_id} > > > > Destroy all flow rules on a port. > > > > Signed-off-by: Adrien Mazarguil <adrien.mazarg...@6wind.com> > > Acked-by: Olga Shern <ol...@mellanox.com> > > --- > > app/test-pmd/cmdline.c | 3 +++ > > app/test-pmd/cmdline_flow.c | 43 > > +++++++++++++++++++++++++++++++++++++++- > > 2 files changed, 45 insertions(+), 1 deletion(-) > > > > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index > > 0dc6c63..6e2b289 100644 > > --- a/app/test-pmd/cmdline.c > > +++ b/app/test-pmd/cmdline.c > > @@ -811,6 +811,9 @@ static void cmd_help_long_parsed(void > > *parsed_result, > > " (select|add)\n" > > " Set the input set for FDir.\n\n" > > > > + "flow flush {port_id}\n" > > + " Destroy all flow rules.\n\n" > > + > > "flow list {port_id} [group {group_id}] [...]\n" > > " List existing flow rules sorted by priority," > > " filtered by group identifiers.\n\n" > > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c > > index bd3da38..49578eb 100644 > > --- a/app/test-pmd/cmdline_flow.c > > +++ b/app/test-pmd/cmdline_flow.c > > @@ -63,6 +63,7 @@ enum index { > > FLOW, > > > > /* Sub-level commands. */ > > + FLUSH, > > LIST, > > > > /* List arguments. */ > > @@ -179,6 +180,9 @@ static const enum index next_list_attr[] = { static int > > parse_init(struct context *, const struct token *, > > const char *, unsigned int, > > void *, unsigned int); > > +static int parse_flush(struct context *, const struct token *, > > + const char *, unsigned int, > > + void *, unsigned int); > > static int parse_list(struct context *, const struct token *, > > const char *, unsigned int, > > void *, unsigned int); > > @@ -240,10 +244,19 @@ static const struct token token_list[] = { > > .name = "flow", > > .type = "{command} {port_id} [{arg} [...]]", > > .help = "manage ingress/egress flow rules", > > - .next = NEXT(NEXT_ENTRY(LIST)), > > + .next = NEXT(NEXT_ENTRY > > + (FLUSH, > > + LIST)), > > .call = parse_init, > > }, > > /* Sub-level commands. */ > > + [FLUSH] = { > > + .name = "flush", > > + .help = "destroy all flow rules", > > + .next = NEXT(NEXT_ENTRY(PORT_ID)), > > + .args = ARGS(ARGS_ENTRY(struct buffer, port)), > > + .call = parse_flush, > > + }, > > [LIST] = { > > .name = "list", > > .help = "list existing flow rules", > > @@ -316,6 +329,31 @@ parse_init(struct context *ctx, const struct token > > *token, > > return len; > > } > > > > +/** Parse tokens for flush command. */ > > +static int > > +parse_flush(struct context *ctx, const struct token *token, > > + const char *str, unsigned int len, > > + void *buf, unsigned int size) > > +{ > > + struct buffer *out = buf; > > + > > + /* Token name must match. */ > > + if (parse_default(ctx, token, str, len, NULL, 0) < 0) > > + return -1; > > + /* Nothing else to do if there is no buffer. */ > > + if (!out) > > + return len; > > + if (!out->command) { > > + if (ctx->curr != FLUSH) > > + return -1; > > + if (sizeof(*out) > size) > > + return -1; > > + out->command = ctx->curr; > > + ctx->object = out; > > + } > > + return len; > > +} > > + > > /** Parse tokens for list command. */ > > static int > > parse_list(struct context *ctx, const struct token *token, @@ -698,6 +736,9 > > @@ static void cmd_flow_parsed(const struct buffer *in) { > > switch (in->command) { > > + case FLUSH: > > + port_flow_flush(in->port); > > + break; > > case LIST: > > port_flow_list(in->port, in->args.list.group_n, > > in->args.list.group); > > -- > > 2.1.4 > > When user flow flush cmd, PMD will flush all the rule on the specific port, > and the memory of which rte_flow point to must be flushed.
Right. > This memory is returned when flow create, will rte layer flush this memory or > PMD is responsible for that memory flush? All handles are considered destroyed and their memory freed, i.e. no rte_flow object remains valid after flush. Applications still need to clean up the memory they allocated to manage these objects, but that's their problem. > BTW, there is no argument about rte_flow in flush function pass into PMD > layer. Right, that's because flush does not request the destruction of a specific rule. PMDs that allocate memory for rte_flow objects must link them together somehow to retrieve them during a flush event. Note this is likely already necessary to clean up the memory allocated for flow rules during dev_close(). -- Adrien Mazarguil 6WIND