Advertisement
Guest User

trace.c

a guest
Aug 22nd, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.20 KB | None | 0 0
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/proc_fs.h>
  4. #include <linux/uaccess.h>
  5. #include "trace.h"
  6. ///////////////////////////////////////////////////////////////////////
  7. // Ring Buffer implementation
  8. struct trace_evt_buffer trace;
  9. unsigned char enabled = 0;
  10. static void increment(int * item)
  11. {
  12.     *item = *item + 1;
  13.     if(*item >= TRACE_BUFFER_SIZE){
  14.     *item = 0;
  15.     }
  16. }
  17. static int is_empty(int r, int w)
  18. {
  19.     return !(r ^ w);
  20.     //xor
  21. }
  22. static int is_full(int r, int w)
  23. {
  24.     int write = w;
  25.     increment(&write);
  26.     return write == r;
  27. }
  28. static int dequeue (char *buffer)
  29. {
  30.     int ret = 0, len;
  31.     char evt[20];
  32.     spin_lock(&trace.lock);
  33.     if(!is_empty(trace.read_item,trace.write_item)){
  34.     //if it is not empty
  35.         switch((int)trace.events[trace.read_item].event){
  36.             case SCHED_TICK:
  37.                 strcpy(evt,"SCH_TK");
  38.                 break;
  39.             case SWITCH_AWAY:
  40.                 strcpy(evt,"SWT_AY");
  41.                 break;
  42.             case SWITCH_TO:
  43.                 strcpy(evt,"SWT_TO");
  44.                 break;
  45.         }
  46.         len = sprintf(buffer,"%llu,",trace.events[trace.read_item].time);
  47.         len += sprintf(buffer+len,"%s,",evt);
  48.         len += sprintf(buffer+len,"pid,%d,",(int)trace.events[trace.read_item].pid);
  49.         len += sprintf(buffer+len,"prio,%d,",(int)trace.events[trace.read_item].prio);
  50.         len += sprintf(buffer+len,"policy,%d,",(int)trace.events[trace.read_item].policy);
  51.         len += sprintf(buffer+len,"state,%d,",(int)trace.events[trace.read_item].state);
  52.         len += sprintf(buffer+len,"%s\n",trace.events[trace.read_item].comm);
  53.         increment(&trace.read_item);
  54.         ret = 1;
  55.     }
  56.     spin_unlock(&trace.lock);
  57.     return ret;
  58. }
  59. static int enqueue (enum evt event, unsigned long long time, struct task_struct *p)
  60. {
  61.     spin_lock(&trace.lock);
  62.     if(is_full(trace.read_item, trace.write_item))
  63.         increment(&trace.read_item);
  64.     trace.events[trace.write_item].event  = event;
  65.     trace.events[trace.write_item].time  = time;
  66.     trace.events[trace.write_item].pid  = p->pid;
  67.     trace.events[trace.write_item].state  = p->state;
  68.     trace.events[trace.write_item].prio  = p->prio;
  69.     trace.events[trace.write_item].policy  = p->policy;
  70.     strcpy(trace.events[trace.write_item].comm, p->comm);
  71.     increment(&trace.write_item);
  72.     spin_unlock(&trace.lock);
  73.     return 1;
  74. }
  75. ssize_t trace_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
  76. {
  77.     char buffer[TRACE_BUFFER_LEN];
  78.     int ret = 0, len = 0;
  79.     printk(KERN_INFO "%s:[%d] read\n",TRACE_ENTRY_NAME, current->pid);
  80.     if(!dequeue(buffer))
  81.         return 0;
  82.     len = strlen(buffer);
  83.     if(len <= 0)
  84.         return -EFAULT;
  85.     if(count < len)
  86.         return -EFAULT;
  87.     ret=copy_to_user(buf,buffer,len);
  88.     if(ret != 0)
  89.         return -EFAULT;
  90.     return len;
  91. }
  92. static const struct file_operations trace_fops = {
  93.     .owner   = THIS_MODULE,
  94.     .read   = trace_read,
  95.     };
  96. static int __init proc_trace_init(void)
  97. {
  98.     proc_create(TRACE_ENTRY_NAME,0444, NULL, &trace_fops);
  99.     printk("CISTER:/proc/%s created\n", TRACE_ENTRY_NAME);
  100.     spin_lock_init(&trace.lock);
  101.     trace.write_item  = 0;
  102.     trace.read_item  = 0;
  103.     enabled   = 1;
  104.     return 0;
  105. }
  106. module_init(proc_trace_init);
  107. //This function will be used to get the event.
  108. void cister_trace(enum evt event, struct task_struct *p)
  109. {
  110.     if(enabled){
  111.         unsigned long long time = ktime_to_ns(ktime_get());
  112.         enqueue(event, time, p);
  113. }
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement