net: mvpp2: debugfs: Allow reading the flow table from debugfs
authorMaxime Chevallier <maxime.chevallier@bootlin.com>
Wed, 27 Mar 2019 08:44:12 +0000 (09:44 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 27 Mar 2019 18:10:57 +0000 (11:10 -0700)
The Classifier flow table is the central part of the PPv2 Classifier,
since it describes all classification steps performed for each flow.

It has 512 entries, shared between all ports, which are divided into
sequences that are pointed-to by the decoding table. Being able to see
which entries in the flow table were hit is a key point when
implementing and debugging classification offload.

This commit allows reading each flow table entry's hit count
independently, with a clear-on-read behaviour.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c

index 5c2f84a2741ebeed5a891acbebb41263e11bb1b3..4100d82eca75c237b3bf0735f4c0fbc209c1a4db 100644 (file)
@@ -23,6 +23,11 @@ struct mvpp2_dbgfs_flow_entry {
        struct mvpp2 *priv;
 };
 
+struct mvpp2_dbgfs_flow_tbl_entry {
+       int id;
+       struct mvpp2 *priv;
+};
+
 struct mvpp2_dbgfs_port_flow_entry {
        struct mvpp2_port *port;
        struct mvpp2_dbgfs_flow_entry *dbg_fe;
@@ -32,6 +37,9 @@ struct mvpp2_dbgfs_entries {
        /* Entries for Header Parser debug info */
        struct mvpp2_dbgfs_prs_entry prs_entries[MVPP2_PRS_TCAM_SRAM_SIZE];
 
+       /* Entries for Classifier Flow Table debug info */
+       struct mvpp2_dbgfs_flow_tbl_entry flt_entries[MVPP2_CLS_FLOWS_TBL_SIZE];
+
        /* Entries for Classifier flows debug info */
        struct mvpp2_dbgfs_flow_entry flow_entries[MVPP2_N_PRS_FLOWS];
 
@@ -41,10 +49,9 @@ struct mvpp2_dbgfs_entries {
 
 static int mvpp2_dbgfs_flow_flt_hits_show(struct seq_file *s, void *unused)
 {
-       struct mvpp2_dbgfs_flow_entry *entry = s->private;
-       int id = MVPP2_FLOW_C2_ENTRY(entry->flow);
+       struct mvpp2_dbgfs_flow_tbl_entry *entry = s->private;
 
-       u32 hits = mvpp2_cls_flow_hits(entry->priv, id);
+       u32 hits = mvpp2_cls_flow_hits(entry->priv, entry->id);
 
        seq_printf(s, "%u\n", hits);
 
@@ -474,9 +481,6 @@ static int mvpp2_dbgfs_flow_entry_init(struct dentry *parent,
        entry->flow = flow;
        entry->priv = priv;
 
-       debugfs_create_file("flow_hits", 0444, flow_entry_dir, entry,
-                           &mvpp2_dbgfs_flow_flt_hits_fops);
-
        debugfs_create_file("dec_hits", 0444, flow_entry_dir, entry,
                            &mvpp2_dbgfs_flow_dec_hits_fops);
 
@@ -575,6 +579,55 @@ static int mvpp2_dbgfs_prs_init(struct dentry *parent, struct mvpp2 *priv)
        return 0;
 }
 
+static int mvpp2_dbgfs_flow_tbl_entry_init(struct dentry *parent,
+                                          struct mvpp2 *priv, int id)
+{
+       struct mvpp2_dbgfs_flow_tbl_entry *entry;
+       struct dentry *flow_tbl_entry_dir;
+       char flow_tbl_entry_name[10];
+
+       if (id >= MVPP2_CLS_FLOWS_TBL_SIZE)
+               return -EINVAL;
+
+       sprintf(flow_tbl_entry_name, "%03d", id);
+
+       flow_tbl_entry_dir = debugfs_create_dir(flow_tbl_entry_name, parent);
+       if (!flow_tbl_entry_dir)
+               return -ENOMEM;
+
+       entry = &priv->dbgfs_entries->flt_entries[id];
+
+       entry->id = id;
+       entry->priv = priv;
+
+       debugfs_create_file("hits", 0444, flow_tbl_entry_dir, entry,
+                           &mvpp2_dbgfs_flow_flt_hits_fops);
+
+       return 0;
+}
+
+static int mvpp2_dbgfs_cls_init(struct dentry *parent, struct mvpp2 *priv)
+{
+       struct dentry *cls_dir, *flow_tbl_dir;
+       int i, ret;
+
+       cls_dir = debugfs_create_dir("classifier", parent);
+       if (!cls_dir)
+               return -ENOMEM;
+
+       flow_tbl_dir = debugfs_create_dir("flow_table", cls_dir);
+       if (!flow_tbl_dir)
+               return -ENOMEM;
+
+       for (i = 0; i < MVPP2_CLS_FLOWS_TBL_SIZE; i++) {
+               ret = mvpp2_dbgfs_flow_tbl_entry_init(flow_tbl_dir, priv, i);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 static int mvpp2_dbgfs_port_init(struct dentry *parent,
                                 struct mvpp2_port *port)
 {
@@ -637,6 +690,10 @@ void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name)
        if (ret)
                goto err;
 
+       ret = mvpp2_dbgfs_cls_init(mvpp2_dir, priv);
+       if (ret)
+               goto err;
+
        for (i = 0; i < priv->port_count; i++) {
                ret = mvpp2_dbgfs_port_init(mvpp2_dir, priv->port_list[i]);
                if (ret)