/* Extract the status field from a kernel handle */
#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)
{
unsigned long *w0 = h;
if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time))
panic("GRU %p is malfunctioning\n", h);
}
+ if (gru_options & OPT_STATS)
+ update_mcs_stats(opc, get_cycles() - start_time);
return status;
}
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)
{
seq_printf(s, "0x%lx\n", gru_options);
if (copy_from_user
(buf, userbuf, count < sizeof(buf) ? count : sizeof(buf)))
return -EFAULT;
+ buf[count - 1] = '\0';
if (!strict_strtoul(buf, 10, &val))
gru_options = val;
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)
{
return single_open(file, options_show, NULL);
.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 = {
.open = options_open,
.read = seq_read,
struct proc_dir_entry *entry;
} proc_files[] = {
{"statistics", 0644, &statistics_fops},
+ {"mcs_statistics", 0644, &mcs_statistics_fops},
{"debug_options", 0644, &options_fops},
{"cch_status", 0444, &cch_fops},
{"gru_status", 0444, &gru_fops},