Processors
Intel® Processors, Tools, and Utilities
15517 Discussions

Using perf_event_open() to get sample address ,however the addr=0

sidrakiyani
Beginner
2,196 Views

I tried to use perf_event_open() to track all the store instructions to get their access address. I found only when I set attr.precise_ip > 0, I can get the non-zero address. But when I ran the same process on vm instead of host, the error massage was "Operation not supported", I can fix this problem by setting precise_ip = 0 on vm, but now I only get bunch of addresses equal to zero. I don't understand why precise_ip is related to the sample addrress which is not pointed out on document, and I also don't understand why I can't set precise_ip = 1 on vm while I can do it on host. Is there anybody can help me??

FYI: I  use - cpu host option when I start vm using qemu-system-x86_64

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/fcntl.h>
#include <sys/syscall.h>
#include <linux/perf_event.h>

#define PERF_PAGES  (1 + (1 << 16))
struct perf_sample {
  struct perf_event_header header;
  __u64 ip;
  __u32 pid, tid;    /* if PERF_SAMPLE_TID */
  __u64 addr;        /* if PERF_SAMPLE_ADDR */
  __u64 weight;      /* if PERF_SAMPLE_WEIGHT */
  /* __u64 data_src;    /\* if PERF_SAMPLE_DATA_SRC *\/ */
  __u64 phy_addr;
};

int perf_event_open(struct perf_event_attr *attr,pid_t pid,int cpu,int group_fd,unsigned long flags)
{
    return syscall(__NR_perf_event_open,attr,pid,cpu,group_fd,flags);
}

void workload()
{
    int i,c=0;
    for(i=0;i<100000000;i++)
    {
        c+=i*i;
        c-=i*100;
        c+=i*i*i/100;
    }
}

int startup()
{
    struct perf_event_attr attr;
    memset(&attr,0,sizeof(struct perf_event_attr));

    attr.type = PERF_TYPE_RAW;
    attr.size = sizeof(struct perf_event_attr);
    attr.config = 0x82d0;
    attr.config1 = 0;
    attr.sample_period = 1000;
    attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_WEIGHT | PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR ;
    attr.disabled = 0;
    //attr.inherit = 1;
    attr.exclude_kernel = 1;
    attr.exclude_hv = 1;
    attr.exclude_callchain_kernel = 1;
    attr.exclude_callchain_user = 1;
    attr.precise_ip = 1; // when i set attr.precise_ip = 0 , all the addr = 0;

    int fd=perf_event_open(&attr,0,-1,-1,0);
    if(fd<0)
    {
        perror("Cannot open perf fd!");
        return -1;
    }
    return fd;
}

void scan_thread(struct perf_event_mmap_page *p)
{
    char *pbuf = (char *)p + p->data_offset;
    __sync_synchronize();

    printf("%d,\n", p->data_size);
    if(p->data_head == p->data_tail) {
        return;
    }
    struct perf_event_header *ph = (void *)(pbuf + (p->data_tail % p->data_size));
    struct perf_sample* ps;
    switch(ph->type) {
        case PERF_RECORD_SAMPLE:
            ps = (struct perf_sample*)ph;
            // assert(ps != NULL);
            if(ps == NULL)
            {
                printf("null\n");
            }
            if(ps!= NULL &&  ps->addr != 0) {
                printf("ip %lx\n", ps->ip);
                printf("tid %d\n", ps->tid);
                printf("addr: %lx \n", ps->addr);
            }
            //printf("addr, %lx\n", ps->addr);
            //printf("phy addr, %lx\n", ps->phy_addr);
            break;
        default:
            printf("type %d\n", ph->type);
            break;
    }
}

int main()
{
    int fd = startup();
    size_t mmap_size = sysconf(_SC_PAGESIZE) * PERF_PAGES;
    struct perf_event_mmap_page *p = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    // start to perf
    ioctl(fd,PERF_EVENT_IOC_ENABLE,0);
    int a= 0;
    while(1)
    {
        // uint64_t instructions;
        // read(fd,&instructions,sizeof(instructions));
        // printf("instructions=%ld\n",instructions);
        // sleep(1);
        workload();
        scan_thread(p);
        sleep(1);
    }
}

 

Labels (1)
0 Kudos
4 Replies
DeividA_Intel
Employee
2,174 Views

Hello sidrakiyani,  

  


Thank you for posting on the Intel® communities.   

  

In order to better assist you, please provide the following:  


1. What is the brand and model name of your processor?

2. What is the toll or program that you are using to run these commands?

3. Are you developing software or working on a project? Can you provide more info about it? 



Best regards, 


Deivid A.  

Intel Customer Support Technician


0 Kudos
DeividA_Intel
Employee
2,155 Views

Hello sidrakiyani, 


Were you able to check the previous post and get the information requested? Please let me know if you need more assistance.   


Regards,  


Deivid A.  

Intel Customer Support Technician  


0 Kudos
megan3000
Valued Contributor I
2,152 Views

Mmmm... it seems like a hidden link is being injected in the text of this post... in the "I" after "FYI"... @DeividA_Intel perhaps this needs to be reported as Spam...

DeividA_Intel
Employee
2,134 Views

Hello sidrakiyani,  

 

We have not heard back from you, so we will close this inquiry. If you need further assistance or if you have additional questions, please create a new thread and we will gladly assist you.  

 

@megan3000 , thanks for your report, I really appreciate it.

 

  

Regards,  

 

Deivid A.  

Intel Customer Support Technician

 

0 Kudos
Reply