Commit e56484da authored by Jack Steiner's avatar Jack Steiner Committed by Linus Torvalds

sgi-gru: add statistics to the GRU context management functions

Add statistics to the GRU context management functions.
Signed-off-by: default avatarJack Steiner <steiner@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a24e5e1c
...@@ -35,6 +35,16 @@ ...@@ -35,6 +35,16 @@
/* Extract the status field from a kernel handle */ /* Extract the status field from a kernel handle */
#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3) #define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3)
struct mcs_op_statistic mcs_op_statistics[mcsop_last];
static void update_mcs_stats(enum mcs_op op, unsigned long clks)
{
atomic_long_inc(&mcs_op_statistics[op].count);
atomic_long_add(clks, &mcs_op_statistics[op].total);
if (mcs_op_statistics[op].max < clks)
mcs_op_statistics[op].max = clks;
}
static void start_instruction(void *h) static void start_instruction(void *h)
{ {
unsigned long *w0 = h; unsigned long *w0 = h;
...@@ -57,6 +67,8 @@ static int wait_instruction_complete(void *h, enum mcs_op opc) ...@@ -57,6 +67,8 @@ static int wait_instruction_complete(void *h, enum mcs_op opc)
if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time)) if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time))
panic("GRU %p is malfunctioning\n", h); panic("GRU %p is malfunctioning\n", h);
} }
if (gru_options & OPT_STATS)
update_mcs_stats(opc, get_cycles() - start_time);
return status; return status;
} }
......
...@@ -122,6 +122,30 @@ static ssize_t statistics_write(struct file *file, const char __user *userbuf, ...@@ -122,6 +122,30 @@ static ssize_t statistics_write(struct file *file, const char __user *userbuf,
return count; return count;
} }
static int mcs_statistics_show(struct seq_file *s, void *p)
{
int op;
unsigned long total, count, max;
static char *id[] = {"cch_allocate", "cch_start", "cch_interrupt",
"cch_interrupt_sync", "cch_deallocate", "tgh_invalidate"};
for (op = 0; op < mcsop_last; op++) {
count = atomic_long_read(&mcs_op_statistics[op].count);
total = atomic_long_read(&mcs_op_statistics[op].total);
max = mcs_op_statistics[op].max;
seq_printf(s, "%-20s%12ld%12ld%12ld\n", id[op], count,
count ? total / count : 0, max);
}
return 0;
}
static ssize_t mcs_statistics_write(struct file *file,
const char __user *userbuf, size_t count, loff_t *data)
{
memset(mcs_op_statistics, 0, sizeof(mcs_op_statistics));
return count;
}
static int options_show(struct seq_file *s, void *p) static int options_show(struct seq_file *s, void *p)
{ {
seq_printf(s, "0x%lx\n", gru_options); seq_printf(s, "0x%lx\n", gru_options);
...@@ -137,6 +161,7 @@ static ssize_t options_write(struct file *file, const char __user *userbuf, ...@@ -137,6 +161,7 @@ static ssize_t options_write(struct file *file, const char __user *userbuf,
if (copy_from_user if (copy_from_user
(buf, userbuf, count < sizeof(buf) ? count : sizeof(buf))) (buf, userbuf, count < sizeof(buf) ? count : sizeof(buf)))
return -EFAULT; return -EFAULT;
buf[count - 1] = '\0';
if (!strict_strtoul(buf, 10, &val)) if (!strict_strtoul(buf, 10, &val))
gru_options = val; gru_options = val;
...@@ -233,6 +258,11 @@ static int statistics_open(struct inode *inode, struct file *file) ...@@ -233,6 +258,11 @@ static int statistics_open(struct inode *inode, struct file *file)
return single_open(file, statistics_show, NULL); return single_open(file, statistics_show, NULL);
} }
static int mcs_statistics_open(struct inode *inode, struct file *file)
{
return single_open(file, mcs_statistics_show, NULL);
}
static int options_open(struct inode *inode, struct file *file) static int options_open(struct inode *inode, struct file *file)
{ {
return single_open(file, options_show, NULL); return single_open(file, options_show, NULL);
...@@ -257,6 +287,14 @@ static const struct file_operations statistics_fops = { ...@@ -257,6 +287,14 @@ static const struct file_operations statistics_fops = {
.release = single_release, .release = single_release,
}; };
static const struct file_operations mcs_statistics_fops = {
.open = mcs_statistics_open,
.read = seq_read,
.write = mcs_statistics_write,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations options_fops = { static const struct file_operations options_fops = {
.open = options_open, .open = options_open,
.read = seq_read, .read = seq_read,
...@@ -285,6 +323,7 @@ static struct proc_entry { ...@@ -285,6 +323,7 @@ static struct proc_entry {
struct proc_dir_entry *entry; struct proc_dir_entry *entry;
} proc_files[] = { } proc_files[] = {
{"statistics", 0644, &statistics_fops}, {"statistics", 0644, &statistics_fops},
{"mcs_statistics", 0644, &mcs_statistics_fops},
{"debug_options", 0644, &options_fops}, {"debug_options", 0644, &options_fops},
{"cch_status", 0444, &cch_fops}, {"cch_status", 0444, &cch_fops},
{"gru_status", 0444, &gru_fops}, {"gru_status", 0444, &gru_fops},
......
...@@ -242,6 +242,14 @@ struct gru_stats_s { ...@@ -242,6 +242,14 @@ struct gru_stats_s {
enum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync, enum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync,
cchop_deallocate, tghop_invalidate, mcsop_last}; cchop_deallocate, tghop_invalidate, mcsop_last};
struct mcs_op_statistic {
atomic_long_t count;
atomic_long_t total;
unsigned long max;
};
extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
#define OPT_DPRINT 1 #define OPT_DPRINT 1
#define OPT_STATS 2 #define OPT_STATS 2
#define GRU_QUICKLOOK 4 #define GRU_QUICKLOOK 4
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment