2 * kernel/vserver/history.c
4 * Virtual Context History Backtrace
6 * Copyright (C) 2004-2005 Herbert Pƶtzl
8 * V0.01 basic structure
9 * V0.02 hash/unhash and trace
10 * V0.03 preemption fixes
14 #include <linux/config.h>
15 #include <linux/errno.h>
16 #include <linux/module.h>
17 #include <linux/types.h>
18 #include <linux/ctype.h>
20 #include <asm/uaccess.h>
21 #include <asm/atomic.h>
22 #include <asm/unistd.h>
24 #include <linux/vserver/debug.h>
27 #ifdef CONFIG_VSERVER_HISTORY
28 #define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE
36 struct _vx_hist_entry entry[VXH_SIZE+1];
40 DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
42 unsigned volatile int vxh_active = 1;
44 static atomic_t sequence = ATOMIC_INIT(0);
49 * requires disabled preemption */
51 struct _vx_hist_entry *vxh_advance(void *loc)
53 unsigned int cpu = smp_processor_id();
54 struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
55 struct _vx_hist_entry *entry;
58 index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
59 entry = &hist->entry[index];
61 entry->seq = atomic_inc_return(&sequence);
67 #define VXH_LOC_FMTS "(#%04x,*%d):%p"
69 #define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc
72 #define VXH_VXI_FMTS "%p[#%d,%d.%d]"
74 #define VXH_VXI_ARGS(e) (e)->vxi.ptr, \
75 (e)->vxi.ptr?(e)->vxi.xid:0, \
76 (e)->vxi.ptr?(e)->vxi.usecnt:0, \
77 (e)->vxi.ptr?(e)->vxi.tasks:0
79 void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
83 printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
88 printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
90 (e->type==VXH_GET_VX_INFO)?"get":"put",
94 case VXH_INIT_VX_INFO:
97 printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
99 (e->type==VXH_INIT_VX_INFO)?"init":
100 ((e->type==VXH_SET_VX_INFO)?"set":"clr"),
101 VXH_VXI_ARGS(e), e->sc.data);
104 case VXH_CLAIM_VX_INFO:
105 case VXH_RELEASE_VX_INFO:
106 printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
108 (e->type==VXH_CLAIM_VX_INFO)?"claim":"release",
109 VXH_VXI_ARGS(e), e->sc.data);
112 case VXH_ALLOC_VX_INFO:
113 case VXH_DEALLOC_VX_INFO:
114 printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
116 (e->type==VXH_ALLOC_VX_INFO)?"alloc":"dealloc",
120 case VXH_HASH_VX_INFO:
121 case VXH_UNHASH_VX_INFO:
122 printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
124 (e->type==VXH_HASH_VX_INFO)?"hash":"unhash",
128 case VXH_LOC_VX_INFO:
129 case VXH_LOOKUP_VX_INFO:
130 case VXH_CREATE_VX_INFO:
131 printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
133 (e->type==VXH_CREATE_VX_INFO)?"create":
134 ((e->type==VXH_LOC_VX_INFO)?"loc":"lookup"),
135 e->ll.arg, VXH_VXI_ARGS(e));
140 static void __vxh_dump_history(void)
144 printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
145 atomic_read(&sequence), NR_CPUS);
147 for (i=0; i < VXH_SIZE; i++) {
148 for (j=0; j < NR_CPUS; j++) {
149 struct _vx_history *hist =
150 &per_cpu(vx_history_buffer, j);
151 unsigned int index = (hist->counter-i) % VXH_SIZE;
152 struct _vx_hist_entry *entry = &hist->entry[index];
154 vxh_dump_entry(entry, j);
159 void vxh_dump_history(void)
167 __vxh_dump_history();
171 /* vserver syscall commands below here */
174 int vc_dump_history(uint32_t id)
177 __vxh_dump_history();
183 EXPORT_SYMBOL_GPL(vxh_advance);