2013-07-23 21:07:08

by Ed L. Cashin

[permalink] [raw]
Subject: [PATCH 0/6] aoe: add debugfs-based export of debug counters

This patch series applies to today's linux-next/akpm, commit
0c2f52fa9a7cb139617078568c48026c49927617.

It adds the debugging information that the coraid.com-distributed aoe
driver exports via sysfs, but instead of sysfs, it uses debugfs.

With these patches applied, even without AoE targets on the network,
KEDR reports new possible memory leaks, but these are from callers
outside the aoe driver that have used aoe_devnode to get the name of
the character devices through the aoe_class->devnode callback, and I
believe they're responsible for freeing that memory.

Ed L. Cashin (6):
aoe: create and destroy debugfs directory for aoe
aoe: add AoE-target files to debugfs
aoe: provide file operations for debugfs files
aoe: fill in per-AoE-target information for debugfs file
aoe: update copyright date
aoe: update internal version number to 85

drivers/block/aoe/aoe.h | 4 +-
drivers/block/aoe/aoeblk.c | 101 +++++++++++++++++++++++++++++++++++++++++++-
drivers/block/aoe/aoedev.c | 1 +
3 files changed, 103 insertions(+), 3 deletions(-)


2013-07-23 21:10:04

by Ed L. Cashin

[permalink] [raw]
Subject: [PATCH 1/6] aoe: create and destroy debugfs directory for aoe

Signed-off-by: Ed Cashin <[email protected]>
---
drivers/block/aoe/aoeblk.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 916d9ed..cb508b7 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -17,11 +17,13 @@
#include <linux/mutex.h>
#include <linux/export.h>
#include <linux/moduleparam.h>
+#include <linux/debugfs.h>
#include <scsi/sg.h>
#include "aoe.h"

static DEFINE_MUTEX(aoeblk_mutex);
static struct kmem_cache *buf_pool_cache;
+static struct dentry *aoe_debugfs_dir;

/* GPFS needs a larger value than the default. */
static int aoe_maxsectors;
@@ -351,6 +353,8 @@ err:
void
aoeblk_exit(void)
{
+ debugfs_remove_recursive(aoe_debugfs_dir);
+ aoe_debugfs_dir = NULL;
kmem_cache_destroy(buf_pool_cache);
}

@@ -362,7 +366,11 @@ aoeblk_init(void)
0, 0, NULL);
if (buf_pool_cache == NULL)
return -ENOMEM;
-
+ aoe_debugfs_dir = debugfs_create_dir("aoe", NULL);
+ if (IS_ERR_OR_NULL(aoe_debugfs_dir)) {
+ pr_info("aoe: cannot create debugfs directory\n");
+ aoe_debugfs_dir = NULL;
+ }
return 0;
}

--
1.7.1

2013-07-23 21:12:08

by Ed L. Cashin

[permalink] [raw]
Subject: [PATCH 2/6] aoe: add AoE-target files to debugfs

Signed-off-by: Ed Cashin <[email protected]>
---
drivers/block/aoe/aoe.h | 2 ++
drivers/block/aoe/aoeblk.c | 35 +++++++++++++++++++++++++++++++++++
drivers/block/aoe/aoedev.c | 1 +
3 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 025c41d..b1f24c5 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -169,6 +169,7 @@ struct aoedev {
ulong ref;
struct work_struct work;/* disk create work struct */
struct gendisk *gd;
+ struct dentry *debugfs;
struct request_queue *blkq;
struct hd_geometry geo;
sector_t ssize;
@@ -206,6 +207,7 @@ struct ktstate {
int aoeblk_init(void);
void aoeblk_exit(void);
void aoeblk_gdalloc(void *);
+void aoedisk_rm_debugfs(struct aoedev *d);
void aoedisk_rm_sysfs(struct aoedev *d);

int aoechr_init(void);
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index cb508b7..d76c5cb 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -132,6 +132,40 @@ static const struct attribute_group attr_group = {
.attrs = aoe_attrs,
};

+static const struct file_operations aoe_debugfs_fops;
+
+static void
+aoedisk_add_debugfs(struct aoedev *d)
+{
+ struct dentry *entry;
+ char *p;
+
+ if (aoe_debugfs_dir == NULL)
+ return;
+ p = strchr(d->gd->disk_name, '/');
+ if (p == NULL)
+ p = d->gd->disk_name;
+ else
+ p++;
+ BUG_ON(*p == '\0');
+ entry = debugfs_create_file(p, 0444, aoe_debugfs_dir, d,
+ &aoe_debugfs_fops);
+ if (IS_ERR_OR_NULL(entry)) {
+ pr_info("aoe: cannot create debugfs file for %s\n",
+ d->gd->disk_name);
+ return;
+ }
+ BUG_ON(d->debugfs);
+ d->debugfs = entry;
+}
+void
+aoedisk_rm_debugfs(struct aoedev *d)
+{
+ BUG_ON(d->debugfs == NULL);
+ debugfs_remove(d->debugfs);
+ d->debugfs = NULL;
+}
+
static int
aoedisk_add_sysfs(struct aoedev *d)
{
@@ -332,6 +366,7 @@ aoeblk_gdalloc(void *vp)

add_disk(gd);
aoedisk_add_sysfs(d);
+ aoedisk_add_debugfs(d);

spin_lock_irqsave(&d->lock, flags);
WARN_ON(!(d->flags & DEVFL_GD_NOW));
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index 784c92e..c904767 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -278,6 +278,7 @@ freedev(struct aoedev *d)

del_timer_sync(&d->timer);
if (d->gd) {
+ aoedisk_rm_debugfs(d);
aoedisk_rm_sysfs(d);
del_gendisk(d->gd);
put_disk(d->gd);
--
1.7.1

2013-07-23 21:14:04

by Ed L. Cashin

[permalink] [raw]
Subject: [PATCH 3/6] aoe: provide file operations for debugfs files

The place holder in the file contents is filled out in the
following patch.

Signed-off-by: Ed Cashin <[email protected]>
---
drivers/block/aoe/aoeblk.c | 25 ++++++++++++++++++++++++-
1 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index d76c5cb..0511d38 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -110,6 +110,24 @@ static ssize_t aoedisk_show_payload(struct device *dev,
return snprintf(page, PAGE_SIZE, "%lu\n", d->maxbcnt);
}

+static int aoedisk_debugfs_show(struct seq_file *s, void *ignored)
+{
+ struct aoedev *d;
+ unsigned long flags;
+
+ d = s->private;
+ spin_lock_irqsave(&d->lock, flags);
+ seq_printf(s, "%s\n", d->gd->disk_name); /* place holder */
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ return 0;
+}
+
+static int aoe_debugfs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, aoedisk_debugfs_show, inode->i_private);
+}
+
static DEVICE_ATTR(state, S_IRUGO, aoedisk_show_state, NULL);
static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL);
static DEVICE_ATTR(netif, S_IRUGO, aoedisk_show_netif, NULL);
@@ -132,7 +150,12 @@ static const struct attribute_group attr_group = {
.attrs = aoe_attrs,
};

-static const struct file_operations aoe_debugfs_fops;
+static const struct file_operations aoe_debugfs_fops = {
+ .open = aoe_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};

static void
aoedisk_add_debugfs(struct aoedev *d)
--
1.7.1

2013-07-23 21:16:04

by Ed L. Cashin

[permalink] [raw]
Subject: [PATCH 4/6] aoe: fill in per-AoE-target information for debugfs file

This information is presented in a compact format that has
evolved for easy routine scanning by expert humans, mostly
developers and support technicians helping to troubleshoot
or test AoE-based systems.

Signed-off-by: Ed Cashin <[email protected]>
---
drivers/block/aoe/aoeblk.c | 33 ++++++++++++++++++++++++++++++++-
1 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 0511d38..b58cbeb 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -113,11 +113,42 @@ static ssize_t aoedisk_show_payload(struct device *dev,
static int aoedisk_debugfs_show(struct seq_file *s, void *ignored)
{
struct aoedev *d;
+ struct aoetgt **t, **te;
+ struct aoeif *ifp, *ife;
unsigned long flags;
+ char c;

d = s->private;
+ seq_printf(s, "rttavg: %d rttdev: %d\n",
+ d->rttavg >> RTTSCALE,
+ d->rttdev >> RTTDSCALE);
+ seq_printf(s, "nskbpool: %d\n", skb_queue_len(&d->skbpool));
+ seq_printf(s, "kicked: %ld\n", d->kicked);
+ seq_printf(s, "maxbcnt: %ld\n", d->maxbcnt);
+ seq_printf(s, "ref: %ld\n", d->ref);
+
spin_lock_irqsave(&d->lock, flags);
- seq_printf(s, "%s\n", d->gd->disk_name); /* place holder */
+ t = d->targets;
+ te = t + d->ntargets;
+ for (; t < te && *t; t++) {
+ c = '\t';
+ seq_printf(s, "falloc: %ld\n", (*t)->falloc);
+ seq_printf(s, "ffree: %p\n",
+ list_empty(&(*t)->ffree) ? NULL : (*t)->ffree.next);
+ seq_printf(s, "%pm:%d:%d:%d\n", (*t)->addr, (*t)->nout,
+ (*t)->maxout, (*t)->nframes);
+ seq_printf(s, "\tssthresh:%d\n", (*t)->ssthresh);
+ seq_printf(s, "\ttaint:%d\n", (*t)->taint);
+ seq_printf(s, "\tr:%d\n", (*t)->rpkts);
+ seq_printf(s, "\tw:%d\n", (*t)->wpkts);
+ ifp = (*t)->ifs;
+ ife = ifp + ARRAY_SIZE((*t)->ifs);
+ for (; ifp->nd && ifp < ife; ifp++) {
+ seq_printf(s, "%c%s", c, ifp->nd->name);
+ c = ',';
+ }
+ seq_puts(s, "\n");
+ }
spin_unlock_irqrestore(&d->lock, flags);

return 0;
--
1.7.1

2013-07-23 21:18:05

by Ed L. Cashin

[permalink] [raw]
Subject: [PATCH 5/6] aoe: update copyright date

Signed-off-by: Ed Cashin <[email protected]>
---
drivers/block/aoe/aoeblk.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index b58cbeb..d63dcf0 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */
+/* Copyright (c) 2013 Coraid, Inc. See COPYING for GPL terms. */
/*
* aoeblk.c
* block device routines
--
1.7.1

2013-07-23 21:20:05

by Ed L. Cashin

[permalink] [raw]
Subject: [PATCH 6/6] aoe: update internal version number to 85

Signed-off-by: Ed Cashin <[email protected]>
---
drivers/block/aoe/aoe.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index b1f24c5..14a9d19 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2013 Coraid, Inc. See COPYING for GPL terms. */
-#define VERSION "83"
+#define VERSION "85"
#define AOE_MAJOR 152
#define DEVICE_NAME "aoe"

--
1.7.1