This is the mail archive of the
systemtap@sources.redhat.com
mailing list for the systemtap project.
Re: runtime libraries application on schedule()
- From: Martin Hunt <hunt at redhat dot com>
- To: William Cohen <wcohen at redhat dot com>
- Cc: SystemTAP <systemtap at sources dot redhat dot com>
- Date: Thu, 10 Mar 2005 02:16:18 -0800
- Subject: Re: runtime libraries application on schedule()
- Organization: Red Hat Inc.
- References: <422F7B3A.8080305@redhat.com>
> Use a jprobe to instrument the entry to schedule().
> Record the pid and the return address.
pid is easy. I don't know of a way to get the return address.
I assume some inline assembly to get ebp or rbp would do it. Something
else to add to the runtime library.
> The information could be analyzed in a sevral different ways:
>
> 1) sum based on return address to find out which schedule points are
> getting hit all the time
> 2) sum the counts by pid to figure out which pids are getting
> rescheduled a lot
That's easy enough.
asmlinkage void __sched inst_schedule(void)
{
_stp_map_key_long (schedpid, current->pid);
_stp_map_set_int64 (schedpid, _stp_map_get_int64(schedstr) + 1);
jprobe_return();
}
I'll attach full source to a working probe.
> 3) find out pid hitting which schedule() points
> 4) find out schedule() point being encountered by which process
I don't understand what you mean by these. What is a schedule point?
Martin
#define HASH_TABLE_BITS 8
#define HASH_TABLE_SIZE (1<<HASH_TABLE_BITS)
#define BUCKETS 16 /* largest histogram width */
#include "../../runtime.h"
#include "../../io.c"
#include "../../map.c"
MODULE_PARM_DESC(stp, "\n");
MAP schedpid, schedstr;
asmlinkage void __sched inst_schedule(void)
{
_stp_map_key_str (schedstr, current->comm);
_stp_map_key_long (schedpid, current->pid);
_stp_map_set_int64 (schedstr, _stp_map_get_int64(schedpid) + 1);
_stp_map_set_int64 (schedpid, _stp_map_get_int64(schedstr) + 1);
jprobe_return();
return;
}
static struct jprobe stp_probes[] = {
{
.kp.addr = (kprobe_opcode_t *)0xc0309408,
.entry = (kprobe_opcode_t *) inst_schedule
},
};
#define MAX_STP_ROUTINE (sizeof(stp_probes)/sizeof(struct jprobe))
static int init_stp(void)
{
int i;
schedpid = _stp_map_new (10000, INT64);
schedstr = _stp_map_new (10000, INT64);
for (i = 0; i < MAX_STP_ROUTINE; i++) {
dlog("plant jprobe at %p, handler addr %p\n",
stp_probes[i].kp.addr, stp_probes[i].entry);
register_jprobe(&stp_probes[i]);
}
dlog("instrumentation is enabled...\n");
return 0;
}
static void cleanup_stp(void)
{
int i;
struct map_node_int64 *ptr;
for (i = 0; i < MAX_STP_ROUTINE; i++)
unregister_jprobe(&stp_probes[i]);
foreach (schedpid, ptr)
dlog ("pid %ld = %lld\n", key1int(ptr), ptr->val);
dlog ("\n");
foreach (schedstr, ptr)
dlog ("process %s = %lld\n", key1str(ptr), ptr->val);
dlog ("\n");
_stp_map_del (schedpid);
_stp_map_del (schedstr);
dlog("EXIT\n");
}
module_init(init_stp);
module_exit(cleanup_stp);
MODULE_LICENSE("GPL");