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