18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file opd_proc.c 38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Management of processes 48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002 OProfile authors 68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING 78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon 98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie 108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_hw_config.h" 138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_proc.h" 148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_image.h" 158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_mapping.h" 168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_sample_files.h" 178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_kernel.h" 188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_24_stats.h" 198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_printf.h" 208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "oprofiled.h" 218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_interface.h" 238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_libiberty.h" 248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <sys/types.h> 268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdio.h> 278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdlib.h> 288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <string.h> 298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* size of process hash table */ 318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define OPD_MAX_PROC_HASH 1024 328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddextern int cpu_number; 348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* hash of process lists */ 368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct list_head opd_procs[OPD_MAX_PROC_HASH]; 378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* statistics purpose */ 398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic int nr_procs; 408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_init_procs(void) 438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int i; 458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (i = 0; i < OPD_MAX_PROC_HASH; i++) 468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_init(&opd_procs[i]); 478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddint opd_get_nr_procs(void) 518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return nr_procs; 538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * proc_hash - hash pid value 588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param tid pid value to hash 598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddinline static uint proc_hash(pid_t tid) 628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* FIXME: hash tgid too! */ 648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return ((tid >> 4) ^ (tid)) % OPD_MAX_PROC_HASH; 658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct opd_proc * opd_new_proc(pid_t tid, pid_t tgid) 698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_proc * proc; 718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd nr_procs++; 738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc = xmalloc(sizeof(struct opd_proc)); 748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_init(&proc->maps); 758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->name = NULL; 768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->tid = tid; 778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->tgid = tgid; 788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->dead = 0; 798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->accessed = 0; 808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_add(&proc->next, &opd_procs[proc_hash(tid)]); 818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return proc; 828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct opd_proc * opd_get_proc(pid_t tid, pid_t tgid) 868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_proc * proc; 888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd uint hash = proc_hash(tid); 898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head * pos, *pos2; 908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_PROC_QUEUE_ACCESS]++; 928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_for_each_safe(pos, pos2, &opd_procs[hash]) { 938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_PROC_QUEUE_DEPTH]++; 948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc = list_entry(pos, struct opd_proc, next); 958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (tid == proc->tid && tgid == proc->tgid) { 968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* LRU to head */ 978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_del(&proc->next); 988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_add(&proc->next, &opd_procs[hash]); 998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return proc; 1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return NULL; 1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * verb_show_sample - print the sample out to the log 1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param offset the offset value 1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param map map to print 1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddinline static void 1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddverb_show_sample(unsigned long offset, struct opd_map * map) 1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vsamples, "DO_PUT_SAMPLE : calc offset 0x%.8lx, " 1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "map start 0x%.8lx, end 0x%.8lx, offset 0x%.8lx, name \"%s\"\n", 1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd offset, map->start, map->end, map->offset, 1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd map->image->name); 1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_put_image_sample(struct opd_image * image, unsigned long offset, 1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd u32 counter) 1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_24_sfile * sfile; 1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int err; 1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (image->ignored) 1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!image->sfiles[cpu_number]) { 1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd image->sfiles[cpu_number] = 1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd xcalloc(OP_MAX_COUNTERS, sizeof(struct op_24_sfile *)); 1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sfile = image->sfiles[cpu_number][counter]; 1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!sfile || !odb_open_count(&sfile->sample_file)) { 1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (opd_open_24_sample_file(image, counter, cpu_number)) { 1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* opd_open_24_sample_file output an error message */ 1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_LOST_SAMPLEFILE]++; 1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sfile = image->sfiles[cpu_number][counter]; 1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd err = odb_update_node(&sfile->sample_file, offset); 1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (err) { 1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd fprintf(stderr, "%s\n", strerror(err)); 1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd abort(); 1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_sfile_lru(sfile); 1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_lookup_maps - lookup a proc mappings for a sample 1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param proc proc to lookup 1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param sample sample to lookup 1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * iterate through the proc maps searching the mapping which owns sample 1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * if sucessful sample count will be updated and we return non-zero 1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic int opd_lookup_maps(struct opd_proc * proc, 1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct op_sample const * sample) 1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head * pos; 1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->accessed = 1; 1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_MAP_ARRAY_ACCESS]++; 1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_for_each(pos, &proc->maps) { 1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_map * map = list_entry(pos, struct opd_map, next); 1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (opd_is_in_map(map, sample->eip)) { 1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd unsigned long offset = opd_map_offset(map, sample->eip); 1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (map->image != NULL) { 1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verb_show_sample(offset, map); 1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_put_image_sample(map->image, offset, sample->counter); 1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_PROCESS]++; 1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 1; 1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_MAP_ARRAY_DEPTH]++; 1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 0; 1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_put_sample(struct op_sample const * sample) 1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_proc * proc; 1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int in_kernel_eip = opd_eip_is_kernel(sample->eip); 1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_SAMPLES]++; 1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vsamples, "DO_PUT_SAMPLE: c%d, EIP 0x%.8lx, tgid %.6d pid %.6d\n", 1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sample->counter, sample->eip, sample->tgid, sample->pid); 1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!separate_kernel && in_kernel_eip) { 2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_handle_kernel_sample(sample->eip, sample->counter); 2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!(proc = opd_get_proc(sample->pid, sample->tgid))) { 2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (in_kernel_eip || no_vmlinux) { 2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* idle task get a 0 pid and is hidden we can never get 2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * a proc so on we fall back to put sample in vmlinux 2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * or module samples files. Here we will catch also 2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * sample for newly created kernel thread, currently 2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * we can handle properly only kenel thread created 2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * at daemon startup time */ 2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_handle_kernel_sample(sample->eip, sample->counter); 2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmisc, "No proc info for tgid %.6d pid %.6d.\n", 2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sample->tgid, sample->pid); 2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_LOST_PROCESS]++; 2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (opd_lookup_maps(proc, sample)) 2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (in_kernel_eip) { 2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_add_kernel_map(proc, sample->eip); 2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (opd_lookup_maps(proc, sample)) 2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* couldn't locate it */ 2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vsamples, "Couldn't find map for pid %.6d, EIP 0x%.8lx.\n", 2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sample->pid, sample->eip); 2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_LOST_MAP_PROCESS]++; 2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_handle_fork(struct op_note const * note) 2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 2408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_proc * old; 2418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_proc * proc; 2428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head * pos; 2438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmisc, "DO_FORK: from %d, %d to %ld, %ld\n", note->pid, note->tgid, 2458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd note->addr, note->len); 2468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd old = opd_get_proc(note->pid, note->tgid); 2488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* we can quite easily get a fork() after the execve() because the 2508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * notifications are racy. In particular, the fork notification is 2518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * done on parent return (so we know the pid), but this will often be 2528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * after the execve is done by the child. 2538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 2548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * So we only create a new setup if it doesn't exist already, allowing 2558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * both the clone() and the execve() cases to work. 2568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 2578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (opd_get_proc(note->addr, note->len)) 2588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 2598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* eip/len is actually tid/tgid of new process */ 2618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc = opd_new_proc(note->addr, note->len); 2628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!old) 2648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 2658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* copy the maps */ 2678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_for_each(pos, &old->maps) { 2688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_map * map = list_entry(pos, struct opd_map, next); 2698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!separate_thread) { 2708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_add_mapping(proc, map->image, map->start, 2718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd map->offset, map->end); 2728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 2738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* when separating thread we can't create blindly a new 2748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * image e.g. pid re-use, multiple mapping with the 2758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * same mapping name etc. */ 2768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_image * image = 2778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_get_image(map->image->name, old->name, 2788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd map->image->kernel, note->addr, note->len); 2798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_add_mapping(proc, image, map->start, map->offset, 2808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd map->end); 2818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 2848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_handle_exec(pid_t tid, pid_t tgid) 2878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 2888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_proc * proc; 2898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmisc, "DO_EXEC: pid %u %u\n", tid, tgid); 2918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* There is a race for samples received between fork/exec sequence. 2938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * These samples belong to the old mapping but we can not say if 2948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * samples has been received before the exec or after. This explains 2958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * the message "Couldn't find map for ..." in verbose mode. 2968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 2978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Unhappily, it is difficult to get an estimation of these misplaced 2988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * samples, the error message can count only out of mapping samples but 2998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * not samples between the race and inside the mapping of the exec'ed 3008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * process :/. 3018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Trying to save old mapping is not correct due the above reason. The 3038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * only manner to handle this is to flush the module samples hash table 3048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * after each fork which is unacceptable for performance reasons */ 3058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc = opd_get_proc(tid, tgid); 3068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (proc) { 3078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_kill_maps(proc); 3088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* proc->name will be set when the next mapping occurs */ 3098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free((char *)proc->name); 3108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->name = NULL; 3118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 3128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_new_proc(tid, tgid); 3138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_handle_exit(struct op_note const * note) 3188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_proc * proc; 3208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmisc, "DO_EXIT: process %d\n", note->pid); 3228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc = opd_get_proc(note->pid, note->tgid); 3248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (proc) { 3258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->dead = 1; 3268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->accessed = 1; 3278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 3288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmisc, "unknown proc %u just exited.\n", note->pid); 3298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef void (*opd_proc_cb)(struct opd_proc *); 3348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 3368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param proc_cb callback to apply onto each existing proc struct 3378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * the callback receive a struct opd_proc * (not a const struct) and is 3398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * allowed to freeze the proc struct itself. 3408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 3418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void opd_for_each_proc(opd_proc_cb proc_cb) 3428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head * pos; 3448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head * pos2; 3458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int i; 3468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (i = 0; i < OPD_MAX_PROC_HASH; ++i) { 3488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_for_each_safe(pos, pos2, &opd_procs[i]) { 3498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_proc * proc = 3508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_entry(pos, struct opd_proc, next); 3518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc_cb(proc); 3528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 3588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_delete_proc - delete a process 3598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param proc process to delete 3608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Remove the process proc from the process list and free 3628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * the associated structures. 3638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 3648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void opd_delete_proc(struct opd_proc * proc) 3658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd --nr_procs; 3678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_del(&proc->next); 3688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_kill_maps(proc); 3698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (proc->name) 3708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free((char *)proc->name); 3718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(proc); 3728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_proc_cleanup(void) 3768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_for_each_proc(opd_delete_proc); 3788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 3828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_age_proc - age a struct opd_proc 3838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param proc proc to age 3848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * age dead proc in such way if a proc doesn't receive any samples 3868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * between two age_proc the opd_proc struct is deleted 3878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 3888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void opd_age_proc(struct opd_proc * proc) 3898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // delay death whilst its still being accessed 3918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (proc->dead) { 3928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->dead += proc->accessed; 3938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd proc->accessed = 0; 3948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (--proc->dead == 0) 3958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_delete_proc(proc); 3968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_age_procs(void) 4018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_for_each_proc(opd_age_proc); 4038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 4048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 4078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_remove_kernel_mapping - remove all kernel mapping for an opd_proc 4088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param proc proc where mappings must be updated. 4098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 4108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * invalidate (by removing them) all kernel mapping. This function do nothing 4118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * when separate_kernel == 0 because we don't add mapping for kernel 4128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * sample in proc struct. 4138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 4148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void opd_remove_kernel_mapping(struct opd_proc * proc) 4158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head * pos, * pos2; 4178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_for_each_safe(pos, pos2, &proc->maps) { 4198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_map * map = list_entry(pos, struct opd_map, next); 4208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (opd_eip_is_kernel(map->start + map->offset)) { 4218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_del(pos); 4228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_delete_image(map->image); 4238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(map); 4248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 4278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_clear_kernel_mapping(void) 4308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_for_each_proc(opd_remove_kernel_mapping); 4328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 433