#ifndef __NEW_DPF__
#define __NEW_DPF__
-#include <linux/list.h>
+#include <linux/hash.h>
#include "storage.h"
struct page_probes {
size_t cnt_ip;
us_proc_ip_t *ip;
- struct hlist_node node; // for file_probes
+ struct hlist_node hlist; // for file_probes
};
struct file_probes {
int loaded;
unsigned long map_addr;
- struct hlist_head head; // for page_probes
+ unsigned long page_probes_hash_bits;
+ struct hlist_head *page_probes_table; // for page_probes
};
struct proc_probes {
static struct page_probes *page_p_new(unsigned long offset, us_proc_ip_t *ip, size_t cnt)
{
struct page_probes *obj = kmalloc(sizeof(*obj), GFP_ATOMIC);
- printk("##### pp_new: offset=%x, cnt_addr=%u\n", offset, cnt);
if (obj) {
int i;
memcpy(obj->ip, ip, sizeof(*obj->ip)*cnt);
obj->cnt_ip = cnt;
obj->offset = offset;
- INIT_HLIST_NODE(&obj->node);
+ INIT_HLIST_NODE(&obj->hlist);
}
return obj;
}
}
+static int calculation_hash_bits(int cnt)
+{
+ int bits;
+ for (bits = 1; cnt >>= 1; ++bits);
+
+ return bits;
+}
+
// file_probes
-static struct file_probes *file_p_new(us_proc_lib_t *lib)
+static struct file_probes *file_p_new(us_proc_lib_t *lib, int page_cnt)
{
struct file_probes *obj = kmalloc(sizeof(*obj), GFP_ATOMIC);
if (obj) {
+ int i, table_size;
obj->dentry = lib->m_f_dentry;
obj->path = lib->path;
obj->loaded = 0;
- INIT_HLIST_HEAD(&obj->head);
+ obj->map_addr = 0;
+
+ obj->page_probes_hash_bits = calculation_hash_bits(page_cnt);//PAGE_PROBES_HASH_BITS;
+ table_size = (1 << obj->page_probes_hash_bits);
+
+ obj->page_probes_table = kmalloc(sizeof(*obj->page_probes_table)*table_size, GFP_ATOMIC);
+
+ for (i = 0; i < table_size; ++i) {
+ INIT_HLIST_HEAD(&obj->page_probes_table[i]);
+ }
}
return obj;
static void file_p_add_page_p(struct file_probes *file_p, struct page_probes *page_p)
{
- hlist_add_head(&page_p->node, &file_p->head);
+ hlist_add_head_rcu(&page_p->hlist, &file_p->page_probes_table[hash_ptr(page_p->offset, file_p->page_probes_hash_bits)]);
}
static struct page_probes *file_p_find_page_p(struct file_probes *file_p, unsigned long page)
{
- struct page_probes *pp = NULL;
- struct hlist_node *node = NULL;
- struct hlist_head *head = &file_p->head;
+ struct page_probes *page_p;
+ struct hlist_node *node;
+ struct hlist_head *head;
unsigned long offset;
if (file_p->map_addr > page) {
offset = page - file_p->map_addr;
- hlist_for_each_entry(pp, node, head, node) {
- if (pp->offset == offset) {
- return pp;
+ head = &file_p->page_probes_table[hash_ptr(offset, file_p->page_probes_hash_bits)];
+ hlist_for_each_entry_rcu(page_p, node, head, hlist) {
+ if (page_p->offset == offset) {
+ return page_p;
}
}
unsigned long cnt = max_index - min_index;
us_proc_ip_t *ip = kmalloc(sizeof(*ip)*cnt, GFP_ATOMIC);
- printk("#### min_index=%2u, max_index=%2u, cnt=%2u\n", min_index, max_index, cnt);
for (idx = min_index; idx < max_index; ++idx) {
ip[idx - min_index].offset = p_ips[idx].offset & ~PAGE_MASK;;
ip[idx - min_index].jprobe = p_ips[idx].jprobe;
return page_p;
}
+static void print_proc_probes(const struct proc_probes *proc_p);
+
struct proc_probes *get_file_probes(const inst_us_proc_t *task_inst_info)
{
struct proc_probes *proc_p = kmalloc(sizeof(*proc_p), GFP_ATOMIC);
for (i = 0; i < task_inst_info->libs_count; ++i) {
us_proc_lib_t *p_libs = &task_inst_info->p_libs[i];
- struct file_probes *file_p = file_p_new(p_libs);
+ struct file_probes *file_p = NULL;
unsigned long page = 0, min_index = 0, max_index = 0, cnt = 0, idx = 0;
struct page_probes *page_p = NULL;
- int k;
- sort_libs(p_libs);
+ int k, page_cnt = 0;
if (p_libs->ips_count == 0) {
continue;
}
- page = p_libs->p_ips[0].offset & PAGE_MASK;
+ sort_libs(p_libs);
- printk("#### page=%x\n", page);
+ // calculation page_cnt
+ page = p_libs->p_ips[0].offset & PAGE_MASK;
min_index = 0;
for (k = 0; k < p_libs->ips_count; ++k) {
us_proc_ip_t *p_ips = &p_libs->p_ips[k];
unsigned long addr = p_ips->offset;
+ if ( page != (addr & PAGE_MASK)) {
+ max_index = k;
+ ++page_cnt;
- printk("#### k=%2u, addr=%x\n", k, addr);
+ page = addr & PAGE_MASK;
+ min_index = max_index;
+ }
+ }
+
+ ++page_cnt;
+
+ printk("### file: %s, page_cnt=%d\n", p_libs->m_f_dentry->d_iname, page_cnt);
+ file_p = file_p_new(p_libs, page_cnt);
+
+ page = p_libs->p_ips[0].offset & PAGE_MASK;
+ min_index = 0;
+ for (k = 0; k < p_libs->ips_count; ++k) {
+ us_proc_ip_t *p_ips = &p_libs->p_ips[k];
+ unsigned long addr = p_ips->offset;
if ( page != (addr & PAGE_MASK)) {
max_index = k;
page_p = get_page_p_of_ips(page, min_index, max_index, p_libs->p_ips);
+
file_p_add_page_p(file_p, page_p);
page = addr & PAGE_MASK;
max_index = p_libs->ips_count;
page_p = get_page_p_of_ips(page, min_index, max_index, p_libs->p_ips);
- file_p_add_page_p(file_p, page_p);
+
+ file_p_add_page_p(file_p, page_p);
proc_p->file_p[i] = file_p;
}
}
+ print_proc_probes(proc_p);
+
return proc_p;
}
static void print_file_probes(const struct file_probes *file_p)
{
+ int i;
struct page_probes *page_p = NULL;
struct hlist_node *node = NULL;
- struct hlist_head *head = &file_p->head;
+ struct hlist_head *head = NULL;
printk("### d_iname=%s, map_addr=%x\n",
file_p->dentry->d_iname, file_p->map_addr);
- hlist_for_each_entry(page_p, node, head, node) {
- print_page_probes(page_p);
+ for (i = 0; i < (1 << file_p->page_probes_hash_bits); ++i) {
+ head = &file_p->page_probes_table[i];
+ hlist_for_each_entry_rcu(page_p, node, head, hlist) {
+ print_page_probes(page_p);
+ }
}
}
-static void print_proc_probes(const struct proc_probes *pp)
+static void print_proc_probes(const struct proc_probes *proc_p)
{
int i;
printk("### print_proc_probes\n");
- for (i = 0; i < pp->cnt; ++i) {
- print_file_probes(pp->file_p[i]);
+ for (i = 0; i < proc_p->cnt; ++i) {
+ print_file_probes(proc_p->file_p[i]);
}
printk("### print_proc_probes\n");
}