forked from Minki/linux
4acc45db71
Currently, HSR manages mac addresses of known HSR nodes by using list_head. It takes a lot of time when there are a lot of registered nodes due to finding specific mac address nodes by using linear search. We can be reducing the time by using hlist. Thus, this patch moves list_head to hlist_head for mac addresses and this allows for further improvement of network performance. Condition: registered 10,000 known HSR nodes Before: # iperf3 -c 192.168.10.1 -i 1 -t 10 Connecting to host 192.168.10.1, port 5201 [ 5] local 192.168.10.2 port 59442 connected to 192.168.10.1 port 5201 [ ID] Interval Transfer Bitrate Retr Cwnd [ 5] 0.00-1.49 sec 3.75 MBytes 21.1 Mbits/sec 0 158 KBytes [ 5] 1.49-2.05 sec 1.25 MBytes 18.7 Mbits/sec 0 166 KBytes [ 5] 2.05-3.06 sec 2.44 MBytes 20.3 Mbits/sec 56 16.9 KBytes [ 5] 3.06-4.08 sec 1.43 MBytes 11.7 Mbits/sec 11 38.0 KBytes [ 5] 4.08-5.00 sec 951 KBytes 8.49 Mbits/sec 0 56.3 KBytes After: # iperf3 -c 192.168.10.1 -i 1 -t 10 Connecting to host 192.168.10.1, port 5201 [ 5] local 192.168.10.2 port 36460 connected to 192.168.10.1 port 5201 [ ID] Interval Transfer Bitrate Retr Cwnd [ 5] 0.00-1.00 sec 7.39 MBytes 62.0 Mbits/sec 3 130 KBytes [ 5] 1.00-2.00 sec 5.06 MBytes 42.4 Mbits/sec 16 113 KBytes [ 5] 2.00-3.00 sec 8.58 MBytes 72.0 Mbits/sec 42 94.3 KBytes [ 5] 3.00-4.00 sec 7.44 MBytes 62.4 Mbits/sec 2 131 KBytes [ 5] 4.00-5.07 sec 8.13 MBytes 63.5 Mbits/sec 38 92.9 KBytes Signed-off-by: Juhee Kang <claudiajkang@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
143 lines
3.8 KiB
C
143 lines
3.8 KiB
C
/*
|
|
* debugfs code for HSR & PRP
|
|
* Copyright (C) 2019 Texas Instruments Incorporated
|
|
*
|
|
* Author(s):
|
|
* Murali Karicheri <m-karicheri2@ti.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation version 2.
|
|
*
|
|
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
|
* kind, whether express or implied; without even the implied warranty
|
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
#include <linux/module.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/jhash.h>
|
|
#include "hsr_main.h"
|
|
#include "hsr_framereg.h"
|
|
|
|
static struct dentry *hsr_debugfs_root_dir;
|
|
|
|
/* hsr_node_table_show - Formats and prints node_table entries */
|
|
static int
|
|
hsr_node_table_show(struct seq_file *sfp, void *data)
|
|
{
|
|
struct hsr_priv *priv = (struct hsr_priv *)sfp->private;
|
|
struct hsr_node *node;
|
|
int i;
|
|
|
|
seq_printf(sfp, "Node Table entries for (%s) device\n",
|
|
(priv->prot_version == PRP_V1 ? "PRP" : "HSR"));
|
|
seq_puts(sfp, "MAC-Address-A, MAC-Address-B, time_in[A], ");
|
|
seq_puts(sfp, "time_in[B], Address-B port, ");
|
|
if (priv->prot_version == PRP_V1)
|
|
seq_puts(sfp, "SAN-A, SAN-B, DAN-P\n");
|
|
else
|
|
seq_puts(sfp, "DAN-H\n");
|
|
|
|
rcu_read_lock();
|
|
|
|
for (i = 0 ; i < priv->hash_buckets; i++) {
|
|
hlist_for_each_entry_rcu(node, &priv->node_db[i], mac_list) {
|
|
/* skip self node */
|
|
if (hsr_addr_is_self(priv, node->macaddress_A))
|
|
continue;
|
|
seq_printf(sfp, "%pM ", &node->macaddress_A[0]);
|
|
seq_printf(sfp, "%pM ", &node->macaddress_B[0]);
|
|
seq_printf(sfp, "%10lx, ",
|
|
node->time_in[HSR_PT_SLAVE_A]);
|
|
seq_printf(sfp, "%10lx, ",
|
|
node->time_in[HSR_PT_SLAVE_B]);
|
|
seq_printf(sfp, "%14x, ", node->addr_B_port);
|
|
|
|
if (priv->prot_version == PRP_V1)
|
|
seq_printf(sfp, "%5x, %5x, %5x\n",
|
|
node->san_a, node->san_b,
|
|
(node->san_a == 0 &&
|
|
node->san_b == 0));
|
|
else
|
|
seq_printf(sfp, "%5x\n", 1);
|
|
}
|
|
}
|
|
rcu_read_unlock();
|
|
return 0;
|
|
}
|
|
|
|
DEFINE_SHOW_ATTRIBUTE(hsr_node_table);
|
|
|
|
void hsr_debugfs_rename(struct net_device *dev)
|
|
{
|
|
struct hsr_priv *priv = netdev_priv(dev);
|
|
struct dentry *d;
|
|
|
|
d = debugfs_rename(hsr_debugfs_root_dir, priv->node_tbl_root,
|
|
hsr_debugfs_root_dir, dev->name);
|
|
if (IS_ERR(d))
|
|
netdev_warn(dev, "failed to rename\n");
|
|
else
|
|
priv->node_tbl_root = d;
|
|
}
|
|
|
|
/* hsr_debugfs_init - create hsr node_table file for dumping
|
|
* the node table
|
|
*
|
|
* Description:
|
|
* When debugfs is configured this routine sets up the node_table file per
|
|
* hsr device for dumping the node_table entries
|
|
*/
|
|
void hsr_debugfs_init(struct hsr_priv *priv, struct net_device *hsr_dev)
|
|
{
|
|
struct dentry *de = NULL;
|
|
|
|
de = debugfs_create_dir(hsr_dev->name, hsr_debugfs_root_dir);
|
|
if (IS_ERR(de)) {
|
|
pr_err("Cannot create hsr debugfs directory\n");
|
|
return;
|
|
}
|
|
|
|
priv->node_tbl_root = de;
|
|
|
|
de = debugfs_create_file("node_table", S_IFREG | 0444,
|
|
priv->node_tbl_root, priv,
|
|
&hsr_node_table_fops);
|
|
if (IS_ERR(de)) {
|
|
pr_err("Cannot create hsr node_table file\n");
|
|
debugfs_remove(priv->node_tbl_root);
|
|
priv->node_tbl_root = NULL;
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* hsr_debugfs_term - Tear down debugfs intrastructure
|
|
*
|
|
* Description:
|
|
* When Debugfs is configured this routine removes debugfs file system
|
|
* elements that are specific to hsr
|
|
*/
|
|
void
|
|
hsr_debugfs_term(struct hsr_priv *priv)
|
|
{
|
|
debugfs_remove_recursive(priv->node_tbl_root);
|
|
priv->node_tbl_root = NULL;
|
|
}
|
|
|
|
void hsr_debugfs_create_root(void)
|
|
{
|
|
hsr_debugfs_root_dir = debugfs_create_dir("hsr", NULL);
|
|
if (IS_ERR(hsr_debugfs_root_dir)) {
|
|
pr_err("Cannot create hsr debugfs root directory\n");
|
|
hsr_debugfs_root_dir = NULL;
|
|
}
|
|
}
|
|
|
|
void hsr_debugfs_remove_root(void)
|
|
{
|
|
/* debugfs_remove() internally checks NULL and ERROR */
|
|
debugfs_remove(hsr_debugfs_root_dir);
|
|
}
|