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

Reply via email to