Commit 613c4e0459603cc04384723b08fd62103b5eaaaf

Authored by Stefan Raspl
Committed by Martin Schwidefsky
1 parent b9c9a33b76

qdio: Keep device-specific dbf entries

Keep the per-device dbf entries until module is removed, with
proper error checking for debug feature setup.

Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

Showing 3 changed files with 77 additions and 13 deletions Side-by-side Diff

drivers/s390/cio/qdio_debug.c
... ... @@ -7,6 +7,7 @@
7 7 #include <linux/debugfs.h>
8 8 #include <linux/uaccess.h>
9 9 #include <linux/export.h>
  10 +#include <linux/slab.h>
10 11 #include <asm/debug.h>
11 12 #include "qdio_debug.h"
12 13 #include "qdio.h"
13 14  
14 15  
... ... @@ -16,11 +17,51 @@
16 17  
17 18 static struct dentry *debugfs_root;
18 19 #define QDIO_DEBUGFS_NAME_LEN 10
  20 +#define QDIO_DBF_NAME_LEN 20
19 21  
20   -void qdio_allocate_dbf(struct qdio_initialize *init_data,
  22 +struct qdio_dbf_entry {
  23 + char dbf_name[QDIO_DBF_NAME_LEN];
  24 + debug_info_t *dbf_info;
  25 + struct list_head dbf_list;
  26 +};
  27 +
  28 +static LIST_HEAD(qdio_dbf_list);
  29 +static DEFINE_MUTEX(qdio_dbf_list_mutex);
  30 +
  31 +static debug_info_t *qdio_get_dbf_entry(char *name)
  32 +{
  33 + struct qdio_dbf_entry *entry;
  34 + debug_info_t *rc = NULL;
  35 +
  36 + mutex_lock(&qdio_dbf_list_mutex);
  37 + list_for_each_entry(entry, &qdio_dbf_list, dbf_list) {
  38 + if (strcmp(entry->dbf_name, name) == 0) {
  39 + rc = entry->dbf_info;
  40 + break;
  41 + }
  42 + }
  43 + mutex_unlock(&qdio_dbf_list_mutex);
  44 + return rc;
  45 +}
  46 +
  47 +static void qdio_clear_dbf_list(void)
  48 +{
  49 + struct qdio_dbf_entry *entry, *tmp;
  50 +
  51 + mutex_lock(&qdio_dbf_list_mutex);
  52 + list_for_each_entry_safe(entry, tmp, &qdio_dbf_list, dbf_list) {
  53 + list_del(&entry->dbf_list);
  54 + debug_unregister(entry->dbf_info);
  55 + kfree(entry);
  56 + }
  57 + mutex_unlock(&qdio_dbf_list_mutex);
  58 +}
  59 +
  60 +int qdio_allocate_dbf(struct qdio_initialize *init_data,
21 61 struct qdio_irq *irq_ptr)
22 62 {
23   - char text[20];
  63 + char text[QDIO_DBF_NAME_LEN];
  64 + struct qdio_dbf_entry *new_entry;
24 65  
25 66 DBF_EVENT("qfmt:%1d", init_data->q_format);
26 67 DBF_HEX(init_data->adapter_name, 8);
... ... @@ -38,11 +79,34 @@
38 79 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
39 80  
40 81 /* allocate trace view for the interface */
41   - snprintf(text, 20, "qdio_%s", dev_name(&init_data->cdev->dev));
42   - irq_ptr->debug_area = debug_register(text, 2, 1, 16);
43   - debug_register_view(irq_ptr->debug_area, &debug_hex_ascii_view);
44   - debug_set_level(irq_ptr->debug_area, DBF_WARN);
45   - DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
  82 + snprintf(text, QDIO_DBF_NAME_LEN, "qdio_%s",
  83 + dev_name(&init_data->cdev->dev));
  84 + irq_ptr->debug_area = qdio_get_dbf_entry(text);
  85 + if (irq_ptr->debug_area)
  86 + DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf reused");
  87 + else {
  88 + irq_ptr->debug_area = debug_register(text, 2, 1, 16);
  89 + if (!irq_ptr->debug_area)
  90 + return -ENOMEM;
  91 + if (debug_register_view(irq_ptr->debug_area,
  92 + &debug_hex_ascii_view)) {
  93 + debug_unregister(irq_ptr->debug_area);
  94 + return -ENOMEM;
  95 + }
  96 + debug_set_level(irq_ptr->debug_area, DBF_WARN);
  97 + DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
  98 + new_entry = kzalloc(sizeof(struct qdio_dbf_entry), GFP_KERNEL);
  99 + if (!new_entry) {
  100 + debug_unregister(irq_ptr->debug_area);
  101 + return -ENOMEM;
  102 + }
  103 + strlcpy(new_entry->dbf_name, text, QDIO_DBF_NAME_LEN);
  104 + new_entry->dbf_info = irq_ptr->debug_area;
  105 + mutex_lock(&qdio_dbf_list_mutex);
  106 + list_add(&new_entry->dbf_list, &qdio_dbf_list);
  107 + mutex_unlock(&qdio_dbf_list_mutex);
  108 + }
  109 + return 0;
46 110 }
47 111  
48 112 static int qstat_show(struct seq_file *m, void *v)
... ... @@ -300,6 +364,7 @@
300 364  
301 365 void qdio_debug_exit(void)
302 366 {
  367 + qdio_clear_dbf_list();
303 368 debugfs_remove(debugfs_root);
304 369 if (qdio_dbf_setup)
305 370 debug_unregister(qdio_dbf_setup);
drivers/s390/cio/qdio_debug.h
... ... @@ -75,7 +75,7 @@
75 75 }
76 76 }
77 77  
78   -void qdio_allocate_dbf(struct qdio_initialize *init_data,
  78 +int qdio_allocate_dbf(struct qdio_initialize *init_data,
79 79 struct qdio_irq *irq_ptr);
80 80 void qdio_setup_debug_entries(struct qdio_irq *irq_ptr,
81 81 struct ccw_device *cdev);
drivers/s390/cio/qdio_main.c
... ... @@ -1233,12 +1233,10 @@
1233 1233 return -ENODEV;
1234 1234  
1235 1235 DBF_EVENT("qfree:%4x", cdev->private->schid.sch_no);
  1236 + DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf abandoned");
1236 1237 mutex_lock(&irq_ptr->setup_mutex);
1237 1238  
1238   - if (irq_ptr->debug_area != NULL) {
1239   - debug_unregister(irq_ptr->debug_area);
1240   - irq_ptr->debug_area = NULL;
1241   - }
  1239 + irq_ptr->debug_area = NULL;
1242 1240 cdev->private->qdio_data = NULL;
1243 1241 mutex_unlock(&irq_ptr->setup_mutex);
1244 1242  
... ... @@ -1275,7 +1273,8 @@
1275 1273 goto out_err;
1276 1274  
1277 1275 mutex_init(&irq_ptr->setup_mutex);
1278   - qdio_allocate_dbf(init_data, irq_ptr);
  1276 + if (qdio_allocate_dbf(init_data, irq_ptr))
  1277 + goto out_rel;
1279 1278  
1280 1279 /*
1281 1280 * Allocate a page for the chsc calls in qdio_establish.