Skip to content

Commit

Permalink
xen: add debugfs support
Browse files Browse the repository at this point in the history
Add support for exporting statistics on mmu updates, multicall
batching and pv spinlocks into debugfs. The base path is xen/ and
each subsystem adds its own directory: mmu, multicalls, spinlocks.

In each directory, writing 1 to "zero_stats" will cause the
corresponding stats to be zeroed the next time they're updated.

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Acked-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Jeremy Fitzhardinge authored and Ingo Molnar committed Aug 21, 2008
1 parent 168d2f4 commit 994025c
Show file tree
Hide file tree
Showing 7 changed files with 580 additions and 9 deletions.
10 changes: 9 additions & 1 deletion arch/x86/xen/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,12 @@ config XEN_MAX_DOMAIN_MEMORY
config XEN_SAVE_RESTORE
bool
depends on PM
default y
default y

config XEN_DEBUG_FS
bool "Enable Xen debug and tuning parameters in debugfs"
depends on XEN && DEBUG_FS
default n
help
Enable statistics output and various tuning options in debugfs.
Enabling this option may incur a significant performance overhead.
3 changes: 2 additions & 1 deletion arch/x86/xen/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ endif
obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
time.o xen-asm_$(BITS).o grant-table.o suspend.o

obj-$(CONFIG_SMP) += smp.o spinlock.o
obj-$(CONFIG_SMP) += smp.o spinlock.o
obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o
123 changes: 123 additions & 0 deletions arch/x86/xen/debugfs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#include <linux/init.h>
#include <linux/debugfs.h>
#include <linux/module.h>

#include "debugfs.h"

static struct dentry *d_xen_debug;

struct dentry * __init xen_init_debugfs(void)
{
if (!d_xen_debug) {
d_xen_debug = debugfs_create_dir("xen", NULL);

if (!d_xen_debug)
pr_warning("Could not create 'xen' debugfs directory\n");
}

return d_xen_debug;
}

struct array_data
{
void *array;
unsigned elements;
};

static int u32_array_open(struct inode *inode, struct file *file)
{
file->private_data = NULL;
return nonseekable_open(inode, file);
}

static size_t format_array(char *buf, size_t bufsize, const char *fmt,
u32 *array, unsigned array_size)
{
size_t ret = 0;
unsigned i;

for(i = 0; i < array_size; i++) {
size_t len;

len = snprintf(buf, bufsize, fmt, array[i]);
len++; /* ' ' or '\n' */
ret += len;

if (buf) {
buf += len;
bufsize -= len;
buf[-1] = (i == array_size-1) ? '\n' : ' ';
}
}

ret++; /* \0 */
if (buf)
*buf = '\0';

return ret;
}

static char *format_array_alloc(const char *fmt, u32 *array, unsigned array_size)
{
size_t len = format_array(NULL, 0, fmt, array, array_size);
char *ret;

ret = kmalloc(len, GFP_KERNEL);
if (ret == NULL)
return NULL;

format_array(ret, len, fmt, array, array_size);
return ret;
}

static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len,
loff_t *ppos)
{
struct inode *inode = file->f_path.dentry->d_inode;
struct array_data *data = inode->i_private;
size_t size;

if (*ppos == 0) {
if (file->private_data) {
kfree(file->private_data);
file->private_data = NULL;
}

file->private_data = format_array_alloc("%u", data->array, data->elements);
}

size = 0;
if (file->private_data)
size = strlen(file->private_data);

return simple_read_from_buffer(buf, len, ppos, file->private_data, size);
}

static int xen_array_release(struct inode *inode, struct file *file)
{
kfree(file->private_data);

return 0;
}

static struct file_operations u32_array_fops = {
.owner = THIS_MODULE,
.open = u32_array_open,
.release= xen_array_release,
.read = u32_array_read,
};

struct dentry *xen_debugfs_create_u32_array(const char *name, mode_t mode,
struct dentry *parent,
u32 *array, unsigned elements)
{
struct array_data *data = kmalloc(sizeof(*data), GFP_KERNEL);

if (data == NULL)
return NULL;

data->array = array;
data->elements = elements;

return debugfs_create_file(name, mode, parent, data, &u32_array_fops);
}
10 changes: 10 additions & 0 deletions arch/x86/xen/debugfs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef _XEN_DEBUGFS_H
#define _XEN_DEBUGFS_H

struct dentry * __init xen_init_debugfs(void);

struct dentry *xen_debugfs_create_u32_array(const char *name, mode_t mode,
struct dentry *parent,
u32 *array, unsigned elements);

#endif /* _XEN_DEBUGFS_H */
Loading

0 comments on commit 994025c

Please sign in to comment.