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/errno.h>
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/ctype.h>
19 #include <asm/uaccess.h>
20 #include <asm/atomic.h>
21 #include <asm/unistd.h>
23 #include <linux/vserver/debug.h>
26 #ifdef CONFIG_VSERVER_HISTORY
27 #define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE
35 struct _vx_hist_entry entry[VXH_SIZE+1];
39 DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
41 unsigned volatile int vxh_active = 1;
43 static atomic_t sequence = ATOMIC_INIT(0);
48 * requires disabled preemption */
50 struct _vx_hist_entry *vxh_advance(void *loc)
52 unsigned int cpu = smp_processor_id();
53 struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
54 struct _vx_hist_entry *entry;
57 index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
58 entry = &hist->entry[index];
60 entry->seq = atomic_inc_return(&sequence);
66 #define VXH_LOC_FMTS "(#%04x,*%d):%p"
68 #define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc
71 #define VXH_VXI_FMTS "%p[#%d,%d.%d]"
73 #define VXH_VXI_ARGS(e) (e)->vxi.ptr, \
74 (e)->vxi.ptr?(e)->vxi.xid:0, \
75 (e)->vxi.ptr?(e)->vxi.usecnt:0, \
76 (e)->vxi.ptr?(e)->vxi.tasks:0
78 void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
82 printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
87 printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
89 (e->type==VXH_GET_VX_INFO)?"get":"put",
93 case VXH_INIT_VX_INFO:
96 printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
98 (e->type==VXH_INIT_VX_INFO)?"init":
99 ((e->type==VXH_SET_VX_INFO)?"set":"clr"),
100 VXH_VXI_ARGS(e), e->sc.data);
103 case VXH_CLAIM_VX_INFO:
104 case VXH_RELEASE_VX_INFO:
105 printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
107 (e->type==VXH_CLAIM_VX_INFO)?"claim":"release",
108 VXH_VXI_ARGS(e), e->sc.data);
111 case VXH_ALLOC_VX_INFO:
112 case VXH_DEALLOC_VX_INFO:
113 printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
115 (e->type==VXH_ALLOC_VX_INFO)?"alloc":"dealloc",
119 case VXH_HASH_VX_INFO:
120 case VXH_UNHASH_VX_INFO:
121 printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
123 (e->type==VXH_HASH_VX_INFO)?"hash":"unhash",
127 case VXH_LOC_VX_INFO:
128 case VXH_LOOKUP_VX_INFO:
129 case VXH_CREATE_VX_INFO:
130 printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
132 (e->type==VXH_CREATE_VX_INFO)?"create":
133 ((e->type==VXH_LOC_VX_INFO)?"loc":"lookup"),
134 e->ll.arg, VXH_VXI_ARGS(e));
139 static void __vxh_dump_history(void)
143 printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
144 atomic_read(&sequence), NR_CPUS);
146 for (i=0; i < VXH_SIZE; i++) {
147 for (j=0; j < NR_CPUS; j++) {
148 struct _vx_history *hist =
149 &per_cpu(vx_history_buffer, j);
150 unsigned int index = (hist->counter-i) % VXH_SIZE;
151 struct _vx_hist_entry *entry = &hist->entry[index];
153 vxh_dump_entry(entry, j);
158 void vxh_dump_history(void)
166 __vxh_dump_history();
170 /* vserver syscall commands below here */
173 int vc_dump_history(uint32_t id)
176 __vxh_dump_history();
182 EXPORT_SYMBOL_GPL(vxh_advance);