s390/qeth: add debugfs file for local IP addresses
authorJulian Wiedmann <jwi@linux.ibm.com>
Wed, 6 May 2020 08:09:42 +0000 (10:09 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 6 May 2020 21:11:26 +0000 (14:11 -0700)
For debugging purposes, provide read access to the local_addr caches
via debug/qeth/<dev_name>/local_addrs.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c

index b92af3735dd4c1ae5364f79b566f26ee65c5bca7..3d8b8e0f24383d56e0ca1e95cb5d91dfdd12ee84 100644 (file)
@@ -11,6 +11,7 @@
 #define __QETH_CORE_H__
 
 #include <linux/completion.h>
+#include <linux/debugfs.h>
 #include <linux/if.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
@@ -797,6 +798,7 @@ struct qeth_card {
        struct qeth_channel data;
 
        struct net_device *dev;
+       struct dentry *debugfs;
        struct qeth_card_stats stats;
        struct qeth_card_info info;
        struct qeth_token token;
index 6b5d42a4501ca2826037b3e791e35b486ecbfa9b..771282cb7aef69ed01754f338f2edab5daa0b9e9 100644 (file)
@@ -61,6 +61,7 @@ EXPORT_SYMBOL_GPL(qeth_core_header_cache);
 static struct kmem_cache *qeth_qdio_outbuf_cache;
 
 static struct device *qeth_core_root_dev;
+static struct dentry *qeth_debugfs_root;
 static struct lock_class_key qdio_out_skb_queue_key;
 
 static void qeth_issue_next_read_cb(struct qeth_card *card,
@@ -805,6 +806,24 @@ static void qeth_del_local_addrs6(struct qeth_card *card,
        spin_unlock(&card->local_addrs6_lock);
 }
 
+static int qeth_debugfs_local_addr_show(struct seq_file *m, void *v)
+{
+       struct qeth_card *card = m->private;
+       struct qeth_local_addr *tmp;
+       unsigned int i;
+
+       rcu_read_lock();
+       hash_for_each_rcu(card->local_addrs4, i, tmp, hnode)
+               seq_printf(m, "%pI4\n", &tmp->addr.s6_addr32[3]);
+       hash_for_each_rcu(card->local_addrs6, i, tmp, hnode)
+               seq_printf(m, "%pI6c\n", &tmp->addr);
+       rcu_read_unlock();
+
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(qeth_debugfs_local_addr);
+
 static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc,
                struct qeth_card *card)
 {
@@ -1608,6 +1627,11 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev)
        if (!card->read_cmd)
                goto out_read_cmd;
 
+       card->debugfs = debugfs_create_dir(dev_name(&gdev->dev),
+                                          qeth_debugfs_root);
+       debugfs_create_file("local_addrs", 0400, card->debugfs, card,
+                           &qeth_debugfs_local_addr_fops);
+
        card->qeth_service_level.seq_print = qeth_core_sl_print;
        register_service_level(&card->qeth_service_level);
        return card;
@@ -5085,9 +5109,11 @@ out_free_nothing:
 static void qeth_core_free_card(struct qeth_card *card)
 {
        QETH_CARD_TEXT(card, 2, "freecrd");
+
+       unregister_service_level(&card->qeth_service_level);
+       debugfs_remove_recursive(card->debugfs);
        qeth_put_cmd(card->read_cmd);
        destroy_workqueue(card->event_wq);
-       unregister_service_level(&card->qeth_service_level);
        dev_set_drvdata(&card->gdev->dev, NULL);
        kfree(card);
 }
@@ -6967,6 +6993,8 @@ static int __init qeth_core_init(void)
 
        pr_info("loading core functions\n");
 
+       qeth_debugfs_root = debugfs_create_dir("qeth", NULL);
+
        rc = qeth_register_dbf_views();
        if (rc)
                goto dbf_err;
@@ -7008,6 +7036,7 @@ slab_err:
 register_err:
        qeth_unregister_dbf_views();
 dbf_err:
+       debugfs_remove_recursive(qeth_debugfs_root);
        pr_err("Initializing the qeth device driver failed\n");
        return rc;
 }
@@ -7021,6 +7050,7 @@ static void __exit qeth_core_exit(void)
        kmem_cache_destroy(qeth_core_header_cache);
        root_device_unregister(qeth_core_root_dev);
        qeth_unregister_dbf_views();
+       debugfs_remove_recursive(qeth_debugfs_root);
        pr_info("core functions removed\n");
 }