1 /** 2 * @file opd_proc.c 3 * Management of processes 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author John Levon 9 * @author Philippe Elie 10 */ 11 12 #include "op_hw_config.h" 13 #include "opd_proc.h" 14 #include "opd_image.h" 15 #include "opd_mapping.h" 16 #include "opd_sample_files.h" 17 #include "opd_kernel.h" 18 #include "opd_24_stats.h" 19 #include "opd_printf.h" 20 #include "oprofiled.h" 21 22 #include "op_interface.h" 23 #include "op_libiberty.h" 24 25 #include <sys/types.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 30 /* size of process hash table */ 31 #define OPD_MAX_PROC_HASH 1024 32 33 extern int cpu_number; 34 35 /* hash of process lists */ 36 static struct list_head opd_procs[OPD_MAX_PROC_HASH]; 37 38 /* statistics purpose */ 39 static int nr_procs; 40 41 42 void opd_init_procs(void) 43 { 44 int i; 45 for (i = 0; i < OPD_MAX_PROC_HASH; i++) 46 list_init(&opd_procs[i]); 47 } 48 49 50 int opd_get_nr_procs(void) 51 { 52 return nr_procs; 53 } 54 55 56 /** 57 * proc_hash - hash pid value 58 * @param tid pid value to hash 59 * 60 */ 61 inline static uint proc_hash(pid_t tid) 62 { 63 /* FIXME: hash tgid too! */ 64 return ((tid >> 4) ^ (tid)) % OPD_MAX_PROC_HASH; 65 } 66 67 68 struct opd_proc * opd_new_proc(pid_t tid, pid_t tgid) 69 { 70 struct opd_proc * proc; 71 72 nr_procs++; 73 proc = xmalloc(sizeof(struct opd_proc)); 74 list_init(&proc->maps); 75 proc->name = NULL; 76 proc->tid = tid; 77 proc->tgid = tgid; 78 proc->dead = 0; 79 proc->accessed = 0; 80 list_add(&proc->next, &opd_procs[proc_hash(tid)]); 81 return proc; 82 } 83 84 85 struct opd_proc * opd_get_proc(pid_t tid, pid_t tgid) 86 { 87 struct opd_proc * proc; 88 uint hash = proc_hash(tid); 89 struct list_head * pos, *pos2; 90 91 opd_24_stats[OPD_PROC_QUEUE_ACCESS]++; 92 list_for_each_safe(pos, pos2, &opd_procs[hash]) { 93 opd_24_stats[OPD_PROC_QUEUE_DEPTH]++; 94 proc = list_entry(pos, struct opd_proc, next); 95 if (tid == proc->tid && tgid == proc->tgid) { 96 /* LRU to head */ 97 list_del(&proc->next); 98 list_add(&proc->next, &opd_procs[hash]); 99 return proc; 100 } 101 } 102 103 return NULL; 104 } 105 106 107 /** 108 * verb_show_sample - print the sample out to the log 109 * @param offset the offset value 110 * @param map map to print 111 */ 112 inline static void 113 verb_show_sample(unsigned long offset, struct opd_map * map) 114 { 115 verbprintf(vsamples, "DO_PUT_SAMPLE : calc offset 0x%.8lx, " 116 "map start 0x%.8lx, end 0x%.8lx, offset 0x%.8lx, name \"%s\"\n", 117 offset, map->start, map->end, map->offset, 118 map->image->name); 119 } 120 121 122 void opd_put_image_sample(struct opd_image * image, unsigned long offset, 123 u32 counter) 124 { 125 struct opd_24_sfile * sfile; 126 int err; 127 128 if (image->ignored) 129 return; 130 131 if (!image->sfiles[cpu_number]) { 132 image->sfiles[cpu_number] = 133 xcalloc(OP_MAX_COUNTERS, sizeof(struct op_24_sfile *)); 134 } 135 sfile = image->sfiles[cpu_number][counter]; 136 137 if (!sfile || !odb_open_count(&sfile->sample_file)) { 138 if (opd_open_24_sample_file(image, counter, cpu_number)) { 139 /* opd_open_24_sample_file output an error message */ 140 opd_24_stats[OPD_LOST_SAMPLEFILE]++; 141 return; 142 } 143 sfile = image->sfiles[cpu_number][counter]; 144 } 145 146 err = odb_update_node(&sfile->sample_file, offset); 147 if (err) { 148 fprintf(stderr, "%s\n", strerror(err)); 149 abort(); 150 } 151 152 opd_24_sfile_lru(sfile); 153 } 154 155 156 /** 157 * opd_lookup_maps - lookup a proc mappings for a sample 158 * @param proc proc to lookup 159 * @param sample sample to lookup 160 * 161 * iterate through the proc maps searching the mapping which owns sample 162 * if sucessful sample count will be updated and we return non-zero 163 */ 164 static int opd_lookup_maps(struct opd_proc * proc, 165 struct op_sample const * sample) 166 { 167 struct list_head * pos; 168 169 proc->accessed = 1; 170 171 opd_24_stats[OPD_MAP_ARRAY_ACCESS]++; 172 list_for_each(pos, &proc->maps) { 173 struct opd_map * map = list_entry(pos, struct opd_map, next); 174 if (opd_is_in_map(map, sample->eip)) { 175 unsigned long offset = opd_map_offset(map, sample->eip); 176 if (map->image != NULL) { 177 verb_show_sample(offset, map); 178 opd_put_image_sample(map->image, offset, sample->counter); 179 } 180 opd_24_stats[OPD_PROCESS]++; 181 return 1; 182 } 183 opd_24_stats[OPD_MAP_ARRAY_DEPTH]++; 184 } 185 186 return 0; 187 } 188 189 190 void opd_put_sample(struct op_sample const * sample) 191 { 192 struct opd_proc * proc; 193 int in_kernel_eip = opd_eip_is_kernel(sample->eip); 194 195 opd_24_stats[OPD_SAMPLES]++; 196 197 verbprintf(vsamples, "DO_PUT_SAMPLE: c%d, EIP 0x%.8lx, tgid %.6d pid %.6d\n", 198 sample->counter, sample->eip, sample->tgid, sample->pid); 199 200 if (!separate_kernel && in_kernel_eip) { 201 opd_handle_kernel_sample(sample->eip, sample->counter); 202 return; 203 } 204 205 if (!(proc = opd_get_proc(sample->pid, sample->tgid))) { 206 if (in_kernel_eip || no_vmlinux) { 207 /* idle task get a 0 pid and is hidden we can never get 208 * a proc so on we fall back to put sample in vmlinux 209 * or module samples files. Here we will catch also 210 * sample for newly created kernel thread, currently 211 * we can handle properly only kenel thread created 212 * at daemon startup time */ 213 opd_handle_kernel_sample(sample->eip, sample->counter); 214 } else { 215 verbprintf(vmisc, "No proc info for tgid %.6d pid %.6d.\n", 216 sample->tgid, sample->pid); 217 opd_24_stats[OPD_LOST_PROCESS]++; 218 } 219 return; 220 } 221 222 if (opd_lookup_maps(proc, sample)) 223 return; 224 225 if (in_kernel_eip) { 226 opd_add_kernel_map(proc, sample->eip); 227 if (opd_lookup_maps(proc, sample)) 228 return; 229 } 230 231 /* couldn't locate it */ 232 verbprintf(vsamples, "Couldn't find map for pid %.6d, EIP 0x%.8lx.\n", 233 sample->pid, sample->eip); 234 opd_24_stats[OPD_LOST_MAP_PROCESS]++; 235 } 236 237 238 void opd_handle_fork(struct op_note const * note) 239 { 240 struct opd_proc * old; 241 struct opd_proc * proc; 242 struct list_head * pos; 243 244 verbprintf(vmisc, "DO_FORK: from %d, %d to %ld, %ld\n", note->pid, note->tgid, 245 note->addr, note->len); 246 247 old = opd_get_proc(note->pid, note->tgid); 248 249 /* we can quite easily get a fork() after the execve() because the 250 * notifications are racy. In particular, the fork notification is 251 * done on parent return (so we know the pid), but this will often be 252 * after the execve is done by the child. 253 * 254 * So we only create a new setup if it doesn't exist already, allowing 255 * both the clone() and the execve() cases to work. 256 */ 257 if (opd_get_proc(note->addr, note->len)) 258 return; 259 260 /* eip/len is actually tid/tgid of new process */ 261 proc = opd_new_proc(note->addr, note->len); 262 263 if (!old) 264 return; 265 266 /* copy the maps */ 267 list_for_each(pos, &old->maps) { 268 struct opd_map * map = list_entry(pos, struct opd_map, next); 269 if (!separate_thread) { 270 opd_add_mapping(proc, map->image, map->start, 271 map->offset, map->end); 272 } else { 273 /* when separating thread we can't create blindly a new 274 * image e.g. pid re-use, multiple mapping with the 275 * same mapping name etc. */ 276 struct opd_image * image = 277 opd_get_image(map->image->name, old->name, 278 map->image->kernel, note->addr, note->len); 279 opd_add_mapping(proc, image, map->start, map->offset, 280 map->end); 281 } 282 } 283 } 284 285 286 void opd_handle_exec(pid_t tid, pid_t tgid) 287 { 288 struct opd_proc * proc; 289 290 verbprintf(vmisc, "DO_EXEC: pid %u %u\n", tid, tgid); 291 292 /* There is a race for samples received between fork/exec sequence. 293 * These samples belong to the old mapping but we can not say if 294 * samples has been received before the exec or after. This explains 295 * the message "Couldn't find map for ..." in verbose mode. 296 * 297 * Unhappily, it is difficult to get an estimation of these misplaced 298 * samples, the error message can count only out of mapping samples but 299 * not samples between the race and inside the mapping of the exec'ed 300 * process :/. 301 * 302 * Trying to save old mapping is not correct due the above reason. The 303 * only manner to handle this is to flush the module samples hash table 304 * after each fork which is unacceptable for performance reasons */ 305 proc = opd_get_proc(tid, tgid); 306 if (proc) { 307 opd_kill_maps(proc); 308 /* proc->name will be set when the next mapping occurs */ 309 free((char *)proc->name); 310 proc->name = NULL; 311 } else { 312 opd_new_proc(tid, tgid); 313 } 314 } 315 316 317 void opd_handle_exit(struct op_note const * note) 318 { 319 struct opd_proc * proc; 320 321 verbprintf(vmisc, "DO_EXIT: process %d\n", note->pid); 322 323 proc = opd_get_proc(note->pid, note->tgid); 324 if (proc) { 325 proc->dead = 1; 326 proc->accessed = 1; 327 } else { 328 verbprintf(vmisc, "unknown proc %u just exited.\n", note->pid); 329 } 330 } 331 332 333 typedef void (*opd_proc_cb)(struct opd_proc *); 334 335 /** 336 * @param proc_cb callback to apply onto each existing proc struct 337 * 338 * the callback receive a struct opd_proc * (not a const struct) and is 339 * allowed to freeze the proc struct itself. 340 */ 341 static void opd_for_each_proc(opd_proc_cb proc_cb) 342 { 343 struct list_head * pos; 344 struct list_head * pos2; 345 int i; 346 347 for (i = 0; i < OPD_MAX_PROC_HASH; ++i) { 348 list_for_each_safe(pos, pos2, &opd_procs[i]) { 349 struct opd_proc * proc = 350 list_entry(pos, struct opd_proc, next); 351 proc_cb(proc); 352 } 353 } 354 } 355 356 357 /** 358 * opd_delete_proc - delete a process 359 * @param proc process to delete 360 * 361 * Remove the process proc from the process list and free 362 * the associated structures. 363 */ 364 static void opd_delete_proc(struct opd_proc * proc) 365 { 366 --nr_procs; 367 list_del(&proc->next); 368 opd_kill_maps(proc); 369 if (proc->name) 370 free((char *)proc->name); 371 free(proc); 372 } 373 374 375 void opd_proc_cleanup(void) 376 { 377 opd_for_each_proc(opd_delete_proc); 378 } 379 380 381 /** 382 * opd_age_proc - age a struct opd_proc 383 * @param proc proc to age 384 * 385 * age dead proc in such way if a proc doesn't receive any samples 386 * between two age_proc the opd_proc struct is deleted 387 */ 388 static void opd_age_proc(struct opd_proc * proc) 389 { 390 // delay death whilst its still being accessed 391 if (proc->dead) { 392 proc->dead += proc->accessed; 393 proc->accessed = 0; 394 if (--proc->dead == 0) 395 opd_delete_proc(proc); 396 } 397 } 398 399 400 void opd_age_procs(void) 401 { 402 opd_for_each_proc(opd_age_proc); 403 } 404 405 406 /** 407 * opd_remove_kernel_mapping - remove all kernel mapping for an opd_proc 408 * @param proc proc where mappings must be updated. 409 * 410 * invalidate (by removing them) all kernel mapping. This function do nothing 411 * when separate_kernel == 0 because we don't add mapping for kernel 412 * sample in proc struct. 413 */ 414 static void opd_remove_kernel_mapping(struct opd_proc * proc) 415 { 416 struct list_head * pos, * pos2; 417 418 list_for_each_safe(pos, pos2, &proc->maps) { 419 struct opd_map * map = list_entry(pos, struct opd_map, next); 420 if (opd_eip_is_kernel(map->start + map->offset)) { 421 list_del(pos); 422 opd_delete_image(map->image); 423 free(map); 424 } 425 } 426 } 427 428 429 void opd_clear_kernel_mapping(void) 430 { 431 opd_for_each_proc(opd_remove_kernel_mapping); 432 } 433