* H. Peter Anvin (hpa@zytor.com) wrote:Peter, do you have something like the following code in mind ? I think the main differences between the code snippet down here and the markers is that markers rely on the compiler to generate the stack setup, and have this code a little bit closer to the function than what I propose here, where I put the stack setup code in a "farfaraway" section. Moreover, markers are much simpler than what I show here. And actually, markers can be deployed portably, with architecture-specific optimizations refined later. This has to be implemented all up front for any traced architecture. In addition, dealing with weird types like unsigned long long can become a pain. Also, due to fact that we are asking the compiler to put keep some variables live in registers, I would be tempted to embed this in a block controlled by an if() statement (conditional branch, like I use for the markers) so we don't have to pay the penality of populating the registers when not required if there are not live at the marker site. Here is the toy program : #include <stdio.h> #define SAVE_REGS \ "pushl %%eax\n\t" \ "pushl %%ebp\n\t" \ "pushl %%edi\n\t" \ "pushl %%esi\n\t" \ "pushl %%edx\n\t" \ "pushl %%ecx\n\t" \ "pushl %%ebx\n\t" #define RESTORE_REGS \ "popl %%ebx\n\t" \ "popl %%ecx\n\t" \ "popl %%edx\n\t" \ "popl %%esi\n\t" \ "popl %%edi\n\t" \ "popl %%ebp\n\t" \ "popl %%eax\n\t" #define asmlinkage __attribute__((regparm(0))) #define _ASM_PTR ".long " struct marker_info { const char *name; const char *fields; unsigned char nr_args; unsigned char type_sizes[]; }; #define trace_mark3(name, fields, arg1, arg2, arg3) \ do { \ static struct marker_info info = { \ #name, \ fields, \ 3, { sizeof(arg1), sizeof(arg2), sizeof(arg3) } }; \ asm (".section __marker_info, \"a\",@progbits\n\t" \ _ASM_PTR "%c0, 1f, 2f\n\t" \ ".previous\n\t" \ ".section __farfarawaycode,\"ax\",@progbits\n\t"\ "1:\n\t" \ SAVE_REGS /* Save caller-saved registers */\ "pushl %3\n\t" \ "pushl %2\n\t" \ "pushl %1\n\t" \ "pushl %0\n\t" \ "call do_kernel_trace\n\t" \ "addl $(4*(1+3)), %%esp\n\t" \ RESTORE_REGS \ "ret\n\t" \ ".previous\n\t" \ "2:\n\t" \ "call 1b\n\t" /* TEST */ \ ".byte 0xe9\n\t"/* jmp near 0x0 (5-bytes 1 insn nop) */\ ".int 0x0\n\t" /* patched to "call ...\n\t" */ \ : : "i" (&info), \ "g" (arg1), "g" (arg2), "g" (arg3)); \ } while (0) /* * Patching address "2f" with a call 1f. All the information required is in * the __marker_info section/table. */ asmlinkage void do_kernel_trace(const struct marker_info *info, unsigned long arg1, unsigned long arg2, unsigned long arg3) { unsigned long *args = &arg1; int i; printf("%s \n", info->name); for (i = 0; i < info->nr_args; i++) { switch (info->type_sizes[i]) { case 1: printf("%hu ", (unsigned char)args[i]); break; case 2: printf("%hu ", (unsigned short)args[i]); break; case 4: printf("%u ", (unsigned int)args[i]); break; case 8: printf("%llu ", (unsigned long long)args[i]); break; } } printf("\n"); } unsigned long long gg = -1ULL; /* this guy does not work. No warning generated. */ void f(void) { char y = 4; trace_mark3(test_event, "name1 name2 name3", y, gg, 6); } void main() { f(); } -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 --
| Srivatsa Vaddagiri | Re: [PATCH, RFC] reimplement flush_workqueue() |
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
| debian developer | Re: Dual-Licensing Linux Kernel with GPL V2 and GPL V3 |
| Rafael J. Wysocki | 2.6.26-rc7-git2: Reported regressions from 2.6.25 |
| Alexey Dobriyan | Re: [GIT]: Networking |
| Gerrit Renker | [PATCH 27/37] dccp: Integration of dynamic feature activation - part 2 (server side) |
| David Miller | Re: [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| Ilpo Järvinen | Re: [bug] stuck localhost TCP connections, v2.6.26-rc3+ |
git: | |
