intermediate result
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 4 Oct 2012 07:26:01 +0000 (11:26 +0400)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 4 Oct 2012 07:26:01 +0000 (11:26 +0400)
driver/device_driver.c
driver/module.c
driver/new_dpf.h [new file with mode: 0644]
driver/probes_manager.c
driver/storage.c
driver/storage.h
driver/us_proc_inst.c
driver/us_proc_inst.h

index 2b5fd74..ffa405f 100644 (file)
@@ -8,7 +8,7 @@
 //      SEE ALSO:       device_driver.h
 //      AUTHOR:         L.Komkov, S.Dianov, S.Grekhov, A.Gerenkov
 //      COMPANY NAME:   Samsung Research Center in Moscow
-//      DEPT NAME:      Advanced Software Group 
+//      DEPT NAME:      Advanced Software Group
 //      CREATED:        2008.02.15
 //      VERSION:        1.0
 //      REVISION DATE:  2008.12.03
@@ -26,6 +26,11 @@ extern unsigned long swap_sum_time;
 extern unsigned long swap_sum_hit;
 #endif
 
+
+extern unsigned long imi_sum_time;
+extern unsigned long imi_sum_hit;
+
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
 static BLOCKING_NOTIFIER_HEAD(swap_notifier_list);
 #endif
@@ -164,20 +169,20 @@ static int device_open(struct inode *inode, struct file *file)
        try_module_get(THIS_MODULE);
        return 0;
 }
+
 static int device_release(struct inode *inode, struct file *file)
 {
        gl_nDeviceOpened--;
        module_put(THIS_MODULE);
        return 0;
 }
+
 static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
 {
        EPRINTF("Operation <<read>> not supported!");
        return -1;
 }
+
 static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
 {
        EPRINTF("Operation <<write>> not supported!");
@@ -519,6 +524,17 @@ static int device_ioctl (struct file *file UNUSED, unsigned int cmd, unsigned lo
                swap_sum_time = 0;
                swap_sum_hit = 0;
 #endif
+
+               printk("\n### imi_sum_time = %ld in install_mapped_ips()\n", imi_sum_time);
+               printk("### imi_sum_hit = %ld in install_mapped_ips()\n", imi_sum_hit);
+
+               if (imi_sum_hit != 0) {
+                       printk("### time = %ld in install_mapped_ips()\n", imi_sum_time/imi_sum_hit);
+               }
+
+               imi_sum_time = 0;
+               imi_sum_hit = 0;
+
                if(ec_user_stop() != 0) {
                        result = -1;
                        goto sad_cleanup;
@@ -609,13 +625,13 @@ sad_cleanup:
                        {
                                if(ioctl_args.len == 0){
                                        result = -EINVAL;
-                                       EPRINTF ("invalid event length!");                                      
+                                       EPRINTF ("invalid event length!");
                                }
                                else {
                                        char *buf = kmalloc(ioctl_args.len, GFP_KERNEL);
                                        if(!buf){
                                                result = -ENOMEM;
-                                               EPRINTF ("failed to alloc mem for event!");                                     
+                                               EPRINTF ("failed to alloc mem for event!");
                                        }
                                        else {
                                                result = copy_from_user (buf, (void *) ioctl_args.data, ioctl_args.len);
@@ -632,7 +648,7 @@ sad_cleanup:
 //                     DPRINTF("User Space Event"); // Frequent call
                        break;
                }
-               
+
        case EC_IOCTL_SET_EVENT_MASK:
                {
                        int mask;
@@ -687,7 +703,7 @@ sad_cleanup:
                        DPRINTF("Set Predefined User Space Probes");
                        break;
                }
-               
+
        case EC_IOCTL_GET_PREDEF_UPROBES:
                {
                        result = get_predef_uprobes((ioctl_predef_uprobes_info_t *)arg);
@@ -698,7 +714,7 @@ sad_cleanup:
                        DPRINTF("Get Predefined User Space Probes");
                        break;
                }
-               
+
        case EC_IOCTL_GET_PREDEF_UPROBES_SIZE:
                {
                        int size = 0;
@@ -715,7 +731,7 @@ sad_cleanup:
                        DPRINTF("Get Size of Predefined User Space Probes");
                        break;
                }
-       
+
        default:
                EPRINTF ("Unknown driver command = %u", cmd);
                result = -EINVAL;
index 487c82b..a25a983 100644 (file)
@@ -8,7 +8,7 @@
 //      SEE ALSO:       module.h
 //      AUTHOR:         L.Komkov, A.Gerenkov
 //      COMPANY NAME:   Samsung Research Center in Moscow
-//      DEPT NAME:      Advanced Software Group 
+//      DEPT NAME:      Advanced Software Group
 //      CREATED:        2008.02.15
 //      VERSION:        1.0
 //      REVISION DATE:  2008.12.03
@@ -68,6 +68,10 @@ void __put_task_struct(struct task_struct *tsk)
 void (*flush_cache_page) (struct vm_area_struct * vma, unsigned long page);
 #endif
 
+#include "../../tools/gpmu/probes/entry_data.h"
+
+storage_arg_t sa_dpf;
+
 static int __init InitializeModule(void)
 {
        if(!fp_kallsyms_lookup_name) {
@@ -112,11 +116,14 @@ static int __init InitializeModule(void)
        INIT_LIST_HEAD(&cond_list.list);
 
        DPRINTF ("is successfully initialized.");
+
+       swap_init_storage_arg(&sa_dpf);
        return 0;
 }
 
 static void __exit UninitializeModule (void)
 {
+       swap_uninit_storage_arg(&sa_dpf);
        ec_user_stop ();
        device_down ();
        probes_manager_down ();
diff --git a/driver/new_dpf.h b/driver/new_dpf.h
new file mode 100644 (file)
index 0000000..2e8ecd2
--- /dev/null
@@ -0,0 +1,303 @@
+#ifndef __NEW_DPF__
+#define __NEW_DPF__
+
+#include <linux/list.h>
+
+
+//struct addr_probe {
+//     unsigned long addr;
+//
+//     struct hlist_node node; // for page_probes
+//};
+
+struct us_proc_ip {
+//     char *name;
+//     int installed;
+       struct jprobe jprobe;
+       struct kretprobe retprobe;
+       unsigned long addr;
+};
+
+struct page_probes {
+       unsigned long page;
+       unsigned long offset;
+
+       struct hlist_node node; // for file_probes
+//     struct hlist_head head; // for addr_probe
+
+       size_t cnt_ip;
+       struct us_proc_ip *ip;
+};
+
+struct file_probes {
+       struct dentry *dentry;
+
+       struct hlist_head head; // for page_probes
+};
+
+struct proc_probes {
+       size_t cnt;
+       struct file_probes **fp;
+};
+
+// addr_probe
+//static struct addr_probe *ap_new(unsigned long addr)
+//{
+//     struct addr_probe *obj = kmalloc(sizeof(*obj), GFP_ATOMIC);
+//
+//     if (obj) {
+//             obj->addr = addr;
+//             INIT_HLIST_NODE(&obj->node);
+//     }
+//
+//     return obj;
+//}
+//
+//static void ap_del(struct addr_probe *ap)
+//{
+//     // TODO: del
+//}
+// addr_probe
+
+// page_probes
+static struct page_probes *pp_new(unsigned long page, struct us_proc_ip *ip, size_t cnt)
+{
+       struct page_probes *obj = kmalloc(sizeof(*obj), GFP_ATOMIC);
+       printk("##### pp_new: page=%x, cnt_addr=%u\n", page, cnt);
+
+       if (obj) {
+               int i;
+               obj->ip = kmalloc(sizeof(*obj->ip)*cnt, GFP_ATOMIC);
+               if(obj->ip == NULL) {
+                       kfree(obj);
+                       return NULL;
+               }
+
+               memcpy(obj->ip, ip, sizeof(*obj->ip)*cnt);
+               obj->cnt_ip = cnt;
+               obj->page = page;
+               obj->offset = 0;
+               INIT_HLIST_NODE(&obj->node);
+       }
+
+       return obj;
+}
+
+static void pp_del(struct page_probes *pp)
+{
+       // TODO: del
+}
+// page_probes
+
+void pp_set_all_kp_addr(struct page_probes *pp)
+{
+       struct us_proc_ip *ip;
+       unsigned long addr;
+       size_t i;
+       for (i = 0; i < pp->cnt_ip; ++i) {
+               ip = &pp->ip[i];
+               addr = ip->addr + pp->offset;
+               ip->retprobe.kp.addr = ip->jprobe.kp.addr = addr;
+       }
+}
+
+// file_probes
+static struct file_probes *fp_new(struct dentry *dentry)
+{
+       struct file_probes *obj = kmalloc(sizeof(*obj), GFP_ATOMIC);
+
+       if (obj) {
+               obj->dentry = dentry;
+               INIT_HLIST_HEAD(&obj->head);
+       }
+
+       return obj;
+}
+
+static void fp_del(struct file_probes *fp)
+{
+       // TODO: del
+}
+
+static void fp_add_pp(struct file_probes *fp, struct page_probes *pp)
+{
+       hlist_add_head(&pp->node, &fp->head);
+}
+
+static struct page_probes *fp_find_pp(struct file_probes *fp, unsigned long page, unsigned long start_addr)
+{
+       struct page_probes *pp = NULL;
+       struct hlist_node *node = NULL;
+       struct hlist_head *head = &fp->head;
+       unsigned long pp_page;
+
+       hlist_for_each_entry(pp, node, head, node) {
+               pp_page = start_addr > pp->page ? start_addr + pp->page : pp->page;
+               if (pp_page == page) {
+                       pp->offset = start_addr > pp->page ? start_addr : 0;
+//                     pp->
+                       return pp;
+               }
+       }
+
+       return NULL;
+}
+// file_probes
+
+
+#include "storage.h"
+#include <linux/sort.h>
+
+static int cmp_func(const void *a, const void *b)
+{
+       us_proc_ip_t *p_ips_a = a;
+       us_proc_ip_t *p_ips_b = b;
+
+       if (p_ips_a->offset < p_ips_b->offset) {
+               return -1;
+       }
+
+       if (p_ips_a->offset > p_ips_b->offset) {
+               return 1;
+       }
+
+       return 0;
+}
+
+static void print_libs(us_proc_lib_t *p_libs, const char *prefix)
+{
+       int k;
+       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;
+               printk("### %s tgid=%u addr = %x\n", prefix, current->tgid, addr);
+       }
+}
+
+static void sort_libs(us_proc_lib_t *p_libs)
+{
+//     print_libs(p_libs, "no_sort");
+       sort(p_libs->p_ips, p_libs->ips_count, sizeof(*p_libs->p_ips), &cmp_func, NULL);
+//     print_libs(p_libs, "sort");
+}
+
+#include "storage.h"
+
+static struct page_probes *get_pp_of_ips(unsigned long page, unsigned long min_index, unsigned long max_index, us_proc_ip_t *p_ips)
+{
+       struct page_probes *pp;
+       unsigned long idx;
+       unsigned long cnt = max_index - min_index;
+       struct us_proc_ip *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].addr = p_ips[idx].offset;
+               ip[idx - min_index].jprobe = p_ips[idx].jprobe;
+               ip[idx - min_index].retprobe = p_ips[idx].retprobe;
+       }
+
+       pp = pp_new(page, ip, cnt);
+       kfree(ip);
+       return pp;
+}
+
+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);
+
+       if (proc_p) {
+               int i;
+               proc_p->cnt = task_inst_info->libs_count;
+               proc_p->fp = kmalloc(sizeof(*proc_p->fp)*proc_p->cnt, 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 *fp = fp_new(p_libs->m_f_dentry);
+                       unsigned long page = 0, min_index = 0, max_index = 0, cnt = 0, idx = 0;
+                       struct page_probes *pp = NULL;
+                       int k;
+                       sort_libs(p_libs);
+
+                       if (p_libs->ips_count == 0) {
+                               continue;
+                       }
+
+                       page = p_libs->p_ips[0].offset & PAGE_MASK;
+                       printk("#### page=%x\n", page);
+                       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;
+
+                               printk("#### k=%2u, addr=%x\n", k, addr);
+                               if ( page != (addr & PAGE_MASK)) {
+                                       max_index = k;
+                                       pp = get_pp_of_ips(page, min_index, max_index, p_libs->p_ips);
+                                       fp_add_pp(fp, pp);
+
+                                       page = addr & PAGE_MASK;
+                                       min_index = max_index;
+                               }
+                       }
+
+                       max_index = p_libs->ips_count;
+                       pp = get_pp_of_ips(page, min_index, max_index, p_libs->p_ips);
+                       fp_add_pp(fp, pp);
+
+                       proc_p->fp[i] = fp;
+               }
+       }
+
+       return proc_p;
+}
+
+// debug
+//static void print_addr_probe(const struct addr_probe *ap)
+//{
+//     printk("###       addr=%x\n", ap->addr);
+//}
+
+static void print_page_probes(const struct page_probes *pp)
+{
+//     struct addr_probe *ap = NULL;
+//     struct hlist_node *node = NULL;
+//     struct hlist_head *head = &pp->head;
+       int i;
+
+       printk("###     page=%x, offset=%x\n", pp->page, pp->offset);
+       for (i = 0; i < pp->cnt_ip; ++i) {
+               printk("###       addr[%2d]=%x\n", i, pp->ip[i].addr);
+       }
+
+
+//     hlist_for_each_entry(ap, node, head, node) {
+//             print_addr_probe(ap);
+//     }
+}
+
+static void print_file_probes(const struct file_probes *fp)
+{
+       struct page_probes *pp = NULL;
+       struct hlist_node *node = NULL;
+       struct hlist_head *head = &fp->head;
+
+       printk("###   d_iname=%s\n", fp->dentry->d_iname);
+
+       hlist_for_each_entry(pp, node, head, node) {
+               print_page_probes(pp);
+       }
+}
+
+static void print_proc_probes(const struct proc_probes *pp)
+{
+       int i;
+
+       printk("### print_proc_probes\n");
+       for (i = 0; i < pp->cnt; ++i) {
+               print_file_probes(pp->fp[i]);
+       }
+       printk("### print_proc_probes\n");
+}
+
+#endif/* __NEW_DPF__ */
index 8b8a212..adc78f9 100644 (file)
@@ -382,6 +382,8 @@ def_jprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long
 
        if (pf_probe == probe)
        {
+               if (us_proc_probes & US_PROC_PF_INSTLD)
+                       do_page_fault_j_pre_code(arg1, arg2, arg3);
 #ifdef CONFIG_X86
                /* FIXME on x86 targets do_page_fault instrumentation may lead to
                 * abnormal termination of some applications (in most cases GUI apps).
index 025bb0d..7827610 100644 (file)
@@ -8,7 +8,7 @@
 //      SEE ALSO:       storage.h
 //      AUTHOR:         L.Komkov, S.Dianov, A.Gerenkov, S.Andreev
 //      COMPANY NAME:   Samsung Research Center in Moscow
-//      DEPT NAME:      Advanced Software Group 
+//      DEPT NAME:      Advanced Software Group
 //      CREATED:        2008.02.15
 //      VERSION:        1.0
 //      REVISION DATE:  2008.12.03
@@ -403,7 +403,7 @@ static int remove_buf (struct dentry *dentry)
         dput (dentry);
         remove_proc_entry (pde->name, pde->parent);
     }
-    
+
     return 0;
 }
 
@@ -482,7 +482,7 @@ int RelayCallbackSubbufStart(struct rchan_buf *buf,
        spin_unlock_irqrestore (&ec_spinlock, spinlock_flags);
        return 1;
 }
+
        /*
           * buf_mapped - relay buffer mmap notification
           * @buf: the channel buffer
@@ -544,7 +544,7 @@ struct dentry * RelayCallbackCreateBufFile(const char *filename,
        return debugfs_create_file(filename, (mode_t)mode, parent, buf, &relay_file_operations);
 #endif // __USE_PROCFS
 }
+
        /*
           * remove_buf_file - remove file representing a relay channel buffer
           * @dentry: the dentry of the file to remove
@@ -988,6 +988,8 @@ void unlink_bundle(void)
        }
 }
 
+struct proc_probes *get_file_probes(const inst_us_proc_t *task_inst_info);
+
 int link_bundle()
 {
        get_my_uprobes_info_t get_uprobes = NULL;
@@ -1508,6 +1510,9 @@ int link_bundle()
 
        p += sizeof(u_int32_t);
 
+
+       us_proc_info.pp = get_file_probes(&us_proc_info);
+
        return 0;
 }
 
@@ -1803,20 +1808,20 @@ int put_us_event (char *data, unsigned long len)
 {
        unsigned long spinlock_flags = 0L;
 
-       SWAP_TYPE_EVENT_HEADER *pEventHeader = (SWAP_TYPE_EVENT_HEADER *)data;  
-       char *cur = data + sizeof(TYPEOF_EVENT_LENGTH) + sizeof(TYPEOF_EVENT_TYPE) 
+       SWAP_TYPE_EVENT_HEADER *pEventHeader = (SWAP_TYPE_EVENT_HEADER *)data;
+       char *cur = data + sizeof(TYPEOF_EVENT_LENGTH) + sizeof(TYPEOF_EVENT_TYPE)
                                + sizeof(TYPEOF_PROBE_ID);
        TYPEOF_NUMBER_OF_ARGS nArgs = pEventHeader->m_nNumberOfArgs;
        TYPEOF_PROBE_ID probe_id = pEventHeader->m_nProbeID;
        //int i;
-       
+
        /*if(probe_id == US_PROBE_ID){
                printk("esrc %p/%d[", data, len);
                for(i = 0; i < len; i++)
                        printk("%02x ", data[i]);
                printk("]\n");
        }*/
-       
+
        // set pid/tid/cpu/time i
        //pEventHeader->m_time.tv_sec = tv.tv_sec;
        //pEventHeader->m_time.tv_usec = tv.tv_usec;
@@ -1859,19 +1864,19 @@ int put_us_event (char *data, unsigned long len)
                cur += sizeof(TYPEOF_TIME);
        }
        //pEventHeader->m_nProcessID = current_tgid;
-       if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_PID)){                
+       if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_PID)){
                //TYPEOF_PROCESS_ID current_tgid = current->tgid;
                (*(TYPEOF_PROCESS_ID *)cur) = current->tgid;
                cur += sizeof(TYPEOF_PROCESS_ID);
        }
        //pEventHeader->m_nThreadID = current_pid;
-       if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_TID)){                
+       if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_TID)){
                //TYPEOF_THREAD_ID current_pid = current->pid;
                (*(TYPEOF_THREAD_ID *)cur) = current->pid;
                cur += sizeof(TYPEOF_THREAD_ID);
        }
        //pEventHeader->m_nCPU = current_cpu;
-       if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_CPU)){                
+       if((probe_id == EVENT_FMT_PROBE_ID) || !(event_mask & IOCTL_EMASK_CPU)){
                //TYPEOF_CPU_NUMBER current_cpu = task_cpu(current);
                (*(TYPEOF_CPU_NUMBER *)cur) = task_cpu(current);
                cur += sizeof(TYPEOF_CPU_NUMBER);
@@ -1879,9 +1884,9 @@ int put_us_event (char *data, unsigned long len)
        //printk("%d %x", probe_id, event_mask);
        // dyn lib event should have all args, it is for internal use and not visible to user
        if((probe_id == EVENT_FMT_PROBE_ID) || (probe_id == DYN_LIB_PROBE_ID) || !(event_mask & IOCTL_EMASK_ARGS)){
-               // move only if any of prev fields has been skipped 
+               // move only if any of prev fields has been skipped
                if(event_mask & (IOCTL_EMASK_TIME|IOCTL_EMASK_PID|IOCTL_EMASK_TID|IOCTL_EMASK_CPU)){
-                       memmove(cur, data+sizeof(SWAP_TYPE_EVENT_HEADER)-sizeof(TYPEOF_NUMBER_OF_ARGS), 
+                       memmove(cur, data+sizeof(SWAP_TYPE_EVENT_HEADER)-sizeof(TYPEOF_NUMBER_OF_ARGS),
                                        len-sizeof(SWAP_TYPE_EVENT_HEADER)+sizeof(TYPEOF_NUMBER_OF_ARGS)
                                        -sizeof(TYPEOF_EVENT_LENGTH));
                }
@@ -1889,7 +1894,7 @@ int put_us_event (char *data, unsigned long len)
                                -sizeof(TYPEOF_EVENT_LENGTH);
        }
        else{
-               // user space probes should have at least one argument to identify them 
+               // user space probes should have at least one argument to identify them
                if((probe_id == US_PROBE_ID) || (probe_id == VTP_PROBE_ID)){
                        char *pArg1;
                        (*(TYPEOF_NUMBER_OF_ARGS *)cur) = 1;
@@ -1906,11 +1911,11 @@ int put_us_event (char *data, unsigned long len)
                        (*(TYPEOF_NUMBER_OF_ARGS *)cur) = 0;
                        cur += sizeof(TYPEOF_NUMBER_OF_ARGS);
                }
-       }       
+       }
        pEventHeader->m_nLength = cur - data + sizeof(TYPEOF_EVENT_LENGTH);
        *((TYPEOF_EVENT_LENGTH *)cur) = pEventHeader->m_nLength;
        len = pEventHeader->m_nLength;
-       
+
        if(WriteEventIntoBuffer(data, len) == -1) {
                EPRINTF("Cannot write event into buffer!");
 
@@ -1968,7 +1973,7 @@ int set_predef_uprobes (ioctl_predef_uprobes_info_t *data)
                        kfree(buf);
                        size += probe_size;
                        continue;
-               }               
+               }
                sep2 = strchr(sep1+1, ':');
                if(!sep2 || (sep2 == sep1) || (sep2+2 == buf+probe_size))
                {
@@ -1976,7 +1981,7 @@ int set_predef_uprobes (ioctl_predef_uprobes_info_t *data)
                        kfree(buf);
                        size += probe_size;
                        continue;
-               }               
+               }
                for(i = 0; i < my_uprobes_info->libs_count; i++)
                {
                        if(strncmp(buf, my_uprobes_info->p_libs[i].path, sep1-buf) != 0)
@@ -1984,7 +1989,7 @@ int set_predef_uprobes (ioctl_predef_uprobes_info_t *data)
                        for(k = 0; k < my_uprobes_info->p_libs[i].ips_count; k++)
                        {
                                if(strncmp(sep1+1, my_uprobes_info->p_libs[i].p_ips[k].name, sep2-sep1-1) != 0)
-                                       continue;                               
+                                       continue;
                                my_uprobes_info->p_libs[i].p_ips[k].offset = simple_strtoul(sep2+1, NULL, 16);
                        }
                }
@@ -2055,7 +2060,7 @@ int get_predef_uprobes(ioctl_predef_uprobes_info_t *udata)
                EPRINTF("failed to copy from user!");
                return -EFAULT;
        }
-               
+
        size = 0;
        for(i = 0; i < my_uprobes_info->libs_count; i++)
        {
index 2c50cc6..1a7bb5c 100644 (file)
@@ -8,7 +8,7 @@
 //      SEE ALSO:       storage.c
 //      AUTHOR:         L.Komkov, S.Dianov, A.Gerenkov
 //      COMPANY NAME:   Samsung Research Center in Moscow
-//      DEPT NAME:      Advanced Software Group 
+//      DEPT NAME:      Advanced Software Group
 //      CREATED:        2008.02.15
 //      VERSION:        1.0
 //      REVISION DATE:  2008.12.03
@@ -179,7 +179,7 @@ typedef struct
        //char *name;
        char type;
        unsigned long size;
-       signed char reg;        // -1 - memory, 0..127 - register number  
+       signed char reg;        // -1 - memory, 0..127 - register number
        long off;
        struct list_head list;
 } us_proc_vtp_data_t;
@@ -200,6 +200,9 @@ typedef struct
        int loaded;
 } us_proc_lib_t;
 
+
+//#include "new_dpf.h"
+
 typedef struct
 {
        char *path;
@@ -217,6 +220,9 @@ typedef struct
        us_proc_ip_t libdvm_entry_ip;
        us_proc_ip_t libdvm_return_ip;
 #endif /* __ANDROID */
+
+       // new_dpf
+       struct proc_probes *pp;
 } inst_us_proc_t;
 
 typedef struct
index ec7e908..c3e3b8d 100644 (file)
@@ -564,7 +564,9 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
        struct hlist_node *node;
        struct task_struct *t;
        struct mm_struct *mm;
-       char path_buffer[256];
+//     char path_buffer[256];
+
+       printk("### install_mapped_ips:\n");
 
        mm = atomic ? task->active_mm : get_task_mm (task);
        if (!mm) {
@@ -1320,6 +1322,161 @@ int inst_usr_space_proc (void)
        return 0;
 }
 
+#include "../../tools/gpmu/probes/entry_data.h"
+
+extern storage_arg_t sa_dpf;
+
+void do_page_fault_j_pre_code(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+       swap_put_entry_data((void *)addr, &sa_dpf);
+
+       unsigned long addr_page_0 = (addr / PAGE_SIZE) * PAGE_SIZE;
+       unsigned long addr_page_1 = (addr >> PAGE_SHIFT) << PAGE_SHIFT;
+       unsigned long addr_page_2 = addr & PAGE_MASK;
+
+//     printk("\n### do_page_fault_j_pre_code: addr=%x, addr_page_0=%x, addr_page_1=%x, addr_page_2=%x\n",
+//                     addr, addr_page_0, addr_page_1, addr_page_2);
+}
+EXPORT_SYMBOL_GPL(do_page_fault_j_pre_code);
+
+
+unsigned long imi_sum_time = 0;
+unsigned long imi_sum_hit = 0;
+EXPORT_SYMBOL_GPL (imi_sum_time);
+EXPORT_SYMBOL_GPL (imi_sum_hit);
+
+
+
+
+#include "new_dpf.h"
+
+
+static void install_page_probes(unsigned long page, struct task_struct *task, struct proc_probes *pp, unsigned long addr)
+{
+       int i;
+       struct vm_area_struct *vma;
+       struct mm_struct *mm = get_task_mm(task);
+
+       printk("### install_page_probes: addr=%x\n", addr);
+       if (mm == NULL) {
+               printk("#### ERRR install_page_probes\n");
+               return;
+       }
+
+//     printk("### for 1\n");
+       down_read(&mm->mmap_sem);
+       for (vma = mm->mmap; vma; vma = vma->vm_next) {
+//             printk("### vma: start=%x, end=%x\n", vma->vm_start, vma->vm_end);
+
+
+               // skip non-text section
+#ifndef __ANDROID
+               if (!(vma->vm_flags & VM_EXEC) || !vma->vm_file || (vma->vm_flags & VM_ACCOUNT) ||
+                       !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
+                       !(vma->vm_flags & (VM_READ | VM_MAYREAD))) {
+#else // __ANDROID
+               if (vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || !vma->vm_file) {
+#endif // __ANDROID
+//                     vma = vma->vm_next;
+                       continue;
+               }
+
+
+
+//             /**
+//              * After process was forked, some time it inherits parent process environment.
+//              * We need to renew instrumentation when we detect that process gets own environment.
+//              */
+//             if (vma->vm_flags & VM_EXECUTABLE) {
+//                     if (!task_inst_info->m_f_dentry) {
+//                             task_inst_info->m_f_dentry = vma->vm_file->f_dentry;
+//                             DPRINTF("initiate dentry tgid = %d, comm = %s", task->tgid, task->comm);
+//                     }
+//                     else if (task_inst_info->m_f_dentry != vma->vm_file->f_dentry) {
+//                             /*
+//                              * All the stuff that cancel instrumentation in old address
+//                              * space are run when do_execve() occurs.  Here we just update
+//                              * dentry because it is changed after do_execve() execution.
+//                              */
+//                             task_inst_info->m_f_dentry = vma->vm_file->f_dentry;
+//                     }
+//             }
+
+
+
+
+               for (i = 0; i < pp->cnt; ++i) {
+                       struct page_probes *page_p = NULL;
+
+                       //TODO: test - try to instrument non-existing libs
+//                     printk("vma: start=%x, name=%s, name_2=%s\n",
+//                                     vma->vm_start,
+//                                     vma->vm_file->f_dentry->d_iname,
+//                                     vma->vm_file->f_dentry->d_name.name);
+                       if (vma->vm_file->f_dentry != pp->fp[i]->dentry) {
+                               continue;
+                       }
+
+//                     if (!(vma->vm_flags & VM_EXECUTABLE) {
+//                     }
+//                     if (page >= vma->vm_start) {
+//                             page -= vma->vm_start;
+//                     }
+
+                       page_p = fp_find_pp(pp->fp[i], page, vma->vm_start);
+
+                       if (page_p) {
+                               printk("### vma: start=%x, addr=%x, name=%s, name_2=%s\n",
+                                               vma->vm_start, addr,
+                                               vma->vm_file->f_dentry->d_iname,
+                                               vma->vm_file->f_dentry->d_name.name);
+                               print_page_probes(page_p);
+                       }
+
+
+//                     for (k = 0; k < task_inst_info->p_libs[i].ips_count; k++) {
+//                             DPRINTF("ips_count current:%d", k);
+//                             if (!task_inst_info->p_libs[i].p_ips[k].installed) {
+//                                     DPRINTF("!installed");
+//                                     addr = task_inst_info->p_libs[i].p_ips[k].offset;
+//                                     if (!(vma->vm_flags & VM_EXECUTABLE)) {
+//                                             /* In the case of prelinking addr is already an
+//                                              * absolute address so we do not need to add
+//                                              * library base address to it.  We use a rule of
+//                                              * thumb here: if addr is greater than library base
+//                                              * address than there is prelinking.
+//                                              */
+//                                             if (addr < vma->vm_start)
+//                                                     addr += vma->vm_start;
+//                                     }
+//                                     if (page_present (mm, addr)) {
+//                                             DPRINTF ("pid %d, %s sym is loaded at %lx/%lx.",
+//                                                     task->pid, task_inst_info->p_libs[i].path,
+//                                                     task_inst_info->p_libs[i].p_ips[k].offset, addr);
+//                                             task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr = (kprobe_opcode_t *) addr;
+//                                             task_inst_info->p_libs[i].p_ips[k].retprobe.kp.addr = (kprobe_opcode_t *) addr;
+//                                             task_inst_info->p_libs[i].p_ips[k].installed = 1;
+//                                             task_inst_info->unres_ips_count--;
+//                                             err = register_usprobe (task, mm, &task_inst_info->p_libs[i].p_ips[k], atomic, 0);
+//                                             if (err != 0) {
+//                                                     DPRINTF ("failed to install IP at %lx/%p. Error %d!",
+//                                                             task_inst_info->p_libs[i].p_ips[k].offset,
+//                                                             task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr, err);
+//                                             }
+//                                     }
+//                             }
+//                     }
+
+
+               }
+       }
+
+       up_read(&mm->mmap_sem);
+       mmput(mm);
+//     printk("### for 2\n");
+
+}
+
 void do_page_fault_ret_pre_code (void)
 {
        struct mm_struct *mm;
@@ -1331,6 +1488,18 @@ void do_page_fault_ret_pre_code (void)
         */
        struct task_struct *task = current->group_leader;
 
+       unsigned long addr = 0, page = 0;
+
+
+       // overhead
+       struct timeval imi_tv1;
+       struct timeval imi_tv2;
+#define USEC_IN_SEC_NUM                                1000000
+
+
+//     struct proc_probes * pp = get_file_probes(&us_proc_info);
+//     print_proc_probes(us_proc_info.pp);
+
        //if user-space instrumentation is not set
        if (!us_proc_info.path)
                return;
@@ -1340,6 +1509,10 @@ void do_page_fault_ret_pre_code (void)
                return;
        }
 
+       addr = (unsigned long)swap_get_entry_data(&sa_dpf);
+       page = addr & PAGE_MASK;
+//     printk("### do_page_fault_ret_pre_code: addr=%x\n", addr);
+
 
        if (!strcmp(us_proc_info.path,"*"))
        {
@@ -1355,7 +1528,15 @@ void do_page_fault_ret_pre_code (void)
                        }
 #endif /* __ANDROID */
                }
+
+               // overhead
+               do_gettimeofday(&imi_tv1);
+               install_page_probes(page, task, us_proc_info.pp, addr);
                install_mapped_ips (task, task_inst_info, 1);
+               do_gettimeofday(&imi_tv2);
+               imi_sum_hit++;
+               imi_sum_time += ((imi_tv2.tv_sec - imi_tv1.tv_sec) *  USEC_IN_SEC_NUM +
+                       (imi_tv2.tv_usec - imi_tv1.tv_usec));
                return;
        }
 
@@ -1417,7 +1598,14 @@ void do_page_fault_ret_pre_code (void)
                        find_libdvm_for_task(task, &us_proc_info);
                }
 #endif /* __ANDROID */
+
+               do_gettimeofday(&imi_tv1);
+               install_page_probes(page, task, us_proc_info.pp, addr);
                install_mapped_ips (task, &us_proc_info, 1);
+               do_gettimeofday(&imi_tv2);
+               imi_sum_hit++;
+               imi_sum_time += ((imi_tv2.tv_sec - imi_tv1.tv_sec) *  USEC_IN_SEC_NUM +
+                       (imi_tv2.tv_usec - imi_tv1.tv_usec));
        }
        //DPRINTF("do_page_fault from proc %d-%d exit", task->pid, task_inst_info->pid);
 }
@@ -1648,6 +1836,10 @@ static int register_usprobe (struct task_struct *task, struct mm_struct *mm, us_
        int ret = 0;
        ip->jprobe.kp.tgid = task->tgid;
        //ip->jprobe.kp.addr = (kprobe_opcode_t *) addr;
+
+       printk("### register_usprobe: offset=%x, j_addr=%x, ret_addr=%x\n",
+                       ip->offset, ip->jprobe.kp.addr, ip->retprobe.kp.addr);
+
        if(!ip->jprobe.entry) {
                if (dbi_ujprobe_event_handler_custom_p != NULL)
                {
index 71e9130..f24cdba 100644 (file)
@@ -28,6 +28,7 @@ extern int inst_usr_space_proc (void);
 extern int deinst_usr_space_proc (void);
 
 /* Detects when IPs are really loaded into phy mem and installs probes. */
+extern void do_page_fault_j_pre_code(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
 extern void do_page_fault_ret_pre_code (void);
 extern void  otg_probe_list_clean(char*);