[PATCH update 1/3] HW-latency: hardware latency test 0.10

2012-11-10 Thread Luming Yu
This patch is the first step to test some basic hardware functions like
TSC to help people understand if there is any hardware latency as well
as throughput problem exposed on bare metal or left behind by BIOS or
interfered by SMI. Currently the patch tests TSC, CPU Frequency and
RDRAND which is a new CPU instruction to get random number introduced in
new CPU like Intel Ivy Bridge in stop_machine context,which is choosen to
make sure testers fully control their system under test to rule out some
level of unwanted noise.

Signed-off-by: Jon Masters 
Signed-off-by: Luming Yu 
---
 drivers/misc/Kconfig   |   6 +
 drivers/misc/Makefile  |   1 +
 drivers/misc/hw_latency_test.c | 939 +
 3 files changed, 946 insertions(+)
 create mode 100644 drivers/misc/hw_latency_test.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b151b7c..a00b039 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -114,6 +114,12 @@ config IBM_ASM
  for information on the specific driver level and support statement
  for your IBM server.
 
+config HW_LATENCY_TEST
+   tristate "Testing module to detect hardware lattency and throughput"
+   depends on DEBUG_FS
+   depends on RING_BUFFER
+   default m
+
 config PHANTOM
tristate "Sensable PHANToM (PCI)"
depends on PCI
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 2129377..c195cce 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -49,3 +49,4 @@ obj-y += carma/
 obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
 obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
 obj-$(CONFIG_INTEL_MEI)+= mei/
+obj-$(CONFIG_HW_LATENCY_TEST)  += hw_latency_test.o
diff --git a/drivers/misc/hw_latency_test.c b/drivers/misc/hw_latency_test.c
new file mode 100644
index 000..0a4d23b
--- /dev/null
+++ b/drivers/misc/hw_latency_test.c
@@ -0,0 +1,939 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define BUF_SIZE_DEFAULT   262144UL
+#define BUF_FLAGS  (RB_FL_OVERWRITE)
+#defineU64STR_SIZE 22
+#define DEBUGFS_BUF_SIZE   1024
+#define DEBUGFS_NAME_SIZE  32
+
+#defineVERSION "0.1.0"
+#define BANNER "hardware latency test"
+#define DRVNAME"hw_latency_test"
+
+#define DEFAULT_SAMPLE_WINDOW  100 
+#defineDEFAULT_SAMPLE_WIDTH50
+#defineDEFAULT_LAT_THRESHOLD   10
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Luming Yu ");
+MODULE_DESCRIPTION("A simple hardware latency test");
+MODULE_VERSION(VERSION);
+
+static int debug;
+static int enabled;
+static int threshold;
+
+module_param(debug, int, 0);
+module_param(enabled, int, 0);
+module_param(threshold, int, 0);
+
+static struct ring_buffer *ring_buffer;
+static DEFINE_MUTEX(ring_buffer_mutex);
+static unsigned long buf_size = 262144UL;
+static struct task_struct *kthread;
+
+#ifdef CONFIG_X86_64
+static u8 *__start = (u8 *)0x8800;
+static u8 *__end = (u8 *)0xc7ff;
+#else
+static u8 *__start = (u8 *)0xc000;
+static u8 *__end = (u8 *)0x;
+#endif
+
+struct sample {
+   unsigned int cpu;
+   u64 seqnum;
+   u64 duration;
+   struct timespec timestamp;
+   u64 addr;
+   u8  unit; /*0: ns 1:us*/
+   unsigned long   lost;
+};
+
+static struct data {
+   struct mutex lock;
+   u64 count;
+   u64 max_sample;
+   u64 threshold;
+
+   u64 sample_window;
+   u64 sample_width;
+
+   atomic_t sample_open;
+
+   wait_queue_head_t wq;
+} data;
+
+static ktime_t now;
+struct sample_function {
+   const char *name;
+   u8  type; /* 0=all parallel, 1=anyone, 2=all sequential*/
+   struct list_head list;
+   int (*get_sample)(void *unused);
+};
+static struct sample_function *current_sample_func = NULL;
+static LIST_HEAD(sample_function_list);
+static DEFINE_MUTEX(sample_function_mutex);
+static int sample_function_register(struct sample_function *sf);
+static struct dentry *debug_dir;
+
+static int sample_function_register(struct sample_function *sf)
+{
+   struct list_head *entry = _function_list;
+   mutex_lock(_function_mutex);
+   list_add(>list, entry);
+   current_sample_func = sf;
+   mutex_unlock(_function_mutex);
+   return 0;
+}
+
+static int __buffer_add_sample(struct sample *sample)
+{
+   return ring_buffer_write(ring_buffer,
+   sizeof(struct sample), sample);
+}
+
+static struct sample *buffer_get_sample(struct sample *sample)
+{
+   struct ring_buffer_event *e = NULL;
+   struct sample *s = NULL;
+   unsigned int cpu = 0;
+
+   if (!sample)
+   return NULL;
+   
+   mutex_lock(_buffer_mutex);
+   for_each_online_cpu(cpu) {
+ 

[PATCH update 1/3] HW-latency: hardware latency test 0.10

2012-11-10 Thread Luming Yu
This patch is the first step to test some basic hardware functions like
TSC to help people understand if there is any hardware latency as well
as throughput problem exposed on bare metal or left behind by BIOS or
interfered by SMI. Currently the patch tests TSC, CPU Frequency and
RDRAND which is a new CPU instruction to get random number introduced in
new CPU like Intel Ivy Bridge in stop_machine context,which is choosen to
make sure testers fully control their system under test to rule out some
level of unwanted noise.

Signed-off-by: Jon Masters j...@redhat.com
Signed-off-by: Luming Yu luming...@intel.com
---
 drivers/misc/Kconfig   |   6 +
 drivers/misc/Makefile  |   1 +
 drivers/misc/hw_latency_test.c | 939 +
 3 files changed, 946 insertions(+)
 create mode 100644 drivers/misc/hw_latency_test.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b151b7c..a00b039 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -114,6 +114,12 @@ config IBM_ASM
  for information on the specific driver level and support statement
  for your IBM server.
 
+config HW_LATENCY_TEST
+   tristate Testing module to detect hardware lattency and throughput
+   depends on DEBUG_FS
+   depends on RING_BUFFER
+   default m
+
 config PHANTOM
tristate Sensable PHANToM (PCI)
depends on PCI
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 2129377..c195cce 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -49,3 +49,4 @@ obj-y += carma/
 obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
 obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
 obj-$(CONFIG_INTEL_MEI)+= mei/
+obj-$(CONFIG_HW_LATENCY_TEST)  += hw_latency_test.o
diff --git a/drivers/misc/hw_latency_test.c b/drivers/misc/hw_latency_test.c
new file mode 100644
index 000..0a4d23b
--- /dev/null
+++ b/drivers/misc/hw_latency_test.c
@@ -0,0 +1,939 @@
+#include linux/module.h
+#include linux/init.h
+#include linux/ring_buffer.h
+#include linux/stop_machine.h
+#include linux/time.h
+#include linux/hrtimer.h
+#include linux/kthread.h
+#include linux/debugfs.h
+#include linux/seq_file.h
+#include linux/uaccess.h
+#include linux/version.h
+#include linux/delay.h
+#include linux/slab.h
+#include linux/random.h
+#include asm/tlbflush.h
+
+#define BUF_SIZE_DEFAULT   262144UL
+#define BUF_FLAGS  (RB_FL_OVERWRITE)
+#defineU64STR_SIZE 22
+#define DEBUGFS_BUF_SIZE   1024
+#define DEBUGFS_NAME_SIZE  32
+
+#defineVERSION 0.1.0
+#define BANNER hardware latency test
+#define DRVNAMEhw_latency_test
+
+#define DEFAULT_SAMPLE_WINDOW  100 
+#defineDEFAULT_SAMPLE_WIDTH50
+#defineDEFAULT_LAT_THRESHOLD   10
+
+MODULE_LICENSE(GPL);
+MODULE_AUTHOR(Luming Yu luming...@gmail.com);
+MODULE_DESCRIPTION(A simple hardware latency test);
+MODULE_VERSION(VERSION);
+
+static int debug;
+static int enabled;
+static int threshold;
+
+module_param(debug, int, 0);
+module_param(enabled, int, 0);
+module_param(threshold, int, 0);
+
+static struct ring_buffer *ring_buffer;
+static DEFINE_MUTEX(ring_buffer_mutex);
+static unsigned long buf_size = 262144UL;
+static struct task_struct *kthread;
+
+#ifdef CONFIG_X86_64
+static u8 *__start = (u8 *)0x8800;
+static u8 *__end = (u8 *)0xc7ff;
+#else
+static u8 *__start = (u8 *)0xc000;
+static u8 *__end = (u8 *)0x;
+#endif
+
+struct sample {
+   unsigned int cpu;
+   u64 seqnum;
+   u64 duration;
+   struct timespec timestamp;
+   u64 addr;
+   u8  unit; /*0: ns 1:us*/
+   unsigned long   lost;
+};
+
+static struct data {
+   struct mutex lock;
+   u64 count;
+   u64 max_sample;
+   u64 threshold;
+
+   u64 sample_window;
+   u64 sample_width;
+
+   atomic_t sample_open;
+
+   wait_queue_head_t wq;
+} data;
+
+static ktime_t now;
+struct sample_function {
+   const char *name;
+   u8  type; /* 0=all parallel, 1=anyone, 2=all sequential*/
+   struct list_head list;
+   int (*get_sample)(void *unused);
+};
+static struct sample_function *current_sample_func = NULL;
+static LIST_HEAD(sample_function_list);
+static DEFINE_MUTEX(sample_function_mutex);
+static int sample_function_register(struct sample_function *sf);
+static struct dentry *debug_dir;
+
+static int sample_function_register(struct sample_function *sf)
+{
+   struct list_head *entry = sample_function_list;
+   mutex_lock(sample_function_mutex);
+   list_add(sf-list, entry);
+   current_sample_func = sf;
+   mutex_unlock(sample_function_mutex);
+   return 0;
+}
+
+static int __buffer_add_sample(struct sample *sample)
+{
+   return ring_buffer_write(ring_buffer,
+   sizeof(struct sample), sample);
+}
+
+static struct sample