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");