Implementing ioctl inside the kernel [closed]
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I am working on Linux kernel 4.19.2. I want to read performance counters available without using perf or any such tool.
From the userspace, I use code as follows.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
#define rdpmc(counter,low,high)
__asm__ __volatile__("rdpmc"
: "=a" (low), "=d" (high)
: "c" (counter))
void test()
printf(".");
static long
perf_event_open (struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
int ret;
ret = syscall (__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
return ret;
int
main ()
unsigned long values1, values2;
unsigned int fixed0, low, high;
struct perf_event_attr pe;
int fd, i;
fixed0 = (1 << 30);
memset (&pe, 0, sizeof (struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof (struct perf_event_attr);
pe.config = PERF_COUNT_HW_INSTRUCTIONS;
pe.disabled = 1;
pe.exclude_kernel = 0;
pe.exclude_user = 0;
pe.exclude_hv = 0;
pe.exclude_idle = 0;
fd = perf_event_open (&pe, 0, -1, -1, 0);
if (fd == -1)
fprintf (stderr, "Error opening leader %llxn", pe.config);
exit (EXIT_FAILURE);
for (i=1; i<=50; i++)
ioctl (fd, PERF_EVENT_IOC_RESET, 0);
ioctl (fd, PERF_EVENT_IOC_ENABLE, 0);
rdpmc (fixed0, low, high);
values1 = ((unsigned long) high << 32) + (unsigned long) low;
test();
rdpmc (fixed0, low, high);
values2 = ((unsigned long) high << 32) + (unsigned long) low;
ioctl (fd, PERF_EVENT_IOC_DISABLE, 0);
printf (" %lun", values2 );
close (fd);
Now I want to implement the same thing in the kernel code.
My goal is that, at every context switch get the count of an event and store it in the task structure. Hence eventually I want the counter to be called from the context_switch() function in the kernel. If I do it from the kernel then I will have the advantage of always running in the context of the current thread.
I think most of the code can be reused from the kernel as well.
I am not sure about the ioctl() part though.
linux linux-kernel
closed as unclear what you're asking by dirkt, sourcejedi, Mr Shunz, ilkkachu, Jeff Schaller♦ Mar 13 at 17:48
Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.
|
show 8 more comments
I am working on Linux kernel 4.19.2. I want to read performance counters available without using perf or any such tool.
From the userspace, I use code as follows.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
#define rdpmc(counter,low,high)
__asm__ __volatile__("rdpmc"
: "=a" (low), "=d" (high)
: "c" (counter))
void test()
printf(".");
static long
perf_event_open (struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
int ret;
ret = syscall (__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
return ret;
int
main ()
unsigned long values1, values2;
unsigned int fixed0, low, high;
struct perf_event_attr pe;
int fd, i;
fixed0 = (1 << 30);
memset (&pe, 0, sizeof (struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof (struct perf_event_attr);
pe.config = PERF_COUNT_HW_INSTRUCTIONS;
pe.disabled = 1;
pe.exclude_kernel = 0;
pe.exclude_user = 0;
pe.exclude_hv = 0;
pe.exclude_idle = 0;
fd = perf_event_open (&pe, 0, -1, -1, 0);
if (fd == -1)
fprintf (stderr, "Error opening leader %llxn", pe.config);
exit (EXIT_FAILURE);
for (i=1; i<=50; i++)
ioctl (fd, PERF_EVENT_IOC_RESET, 0);
ioctl (fd, PERF_EVENT_IOC_ENABLE, 0);
rdpmc (fixed0, low, high);
values1 = ((unsigned long) high << 32) + (unsigned long) low;
test();
rdpmc (fixed0, low, high);
values2 = ((unsigned long) high << 32) + (unsigned long) low;
ioctl (fd, PERF_EVENT_IOC_DISABLE, 0);
printf (" %lun", values2 );
close (fd);
Now I want to implement the same thing in the kernel code.
My goal is that, at every context switch get the count of an event and store it in the task structure. Hence eventually I want the counter to be called from the context_switch() function in the kernel. If I do it from the kernel then I will have the advantage of always running in the context of the current thread.
I think most of the code can be reused from the kernel as well.
I am not sure about the ioctl() part though.
linux linux-kernel
closed as unclear what you're asking by dirkt, sourcejedi, Mr Shunz, ilkkachu, Jeff Schaller♦ Mar 13 at 17:48
Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.
@sourcejedi This ioctl() would be calling something in the kernel right? I want to do it from there directly. Am I missing something here?
– Nikhilesh Singh
Mar 13 at 11:08
1
@NikhileshSingh I assume that doesn't crash, but your program does not explain unambiguously on its own. You are reading a per-cpu counter. You have not shown what your intention is v.s. Linux choosing to migrate your process between different cpus while it is running. Your english language description doesn't say anything about which CPU(s) you want counter values from either.
– sourcejedi
Mar 13 at 12:06
1
Also you still haven't explained why you think you can do the__NR_perf_event_open()
part from the kernel. Why are you confident about that part, but you need to ask aboutioctl()
? That would be a nice clear way to show "where you got stuck", and the specific answer you seem to be looking for.
– sourcejedi
Mar 13 at 12:10
1
I was going to suggest if this should have been on SO, but you seem to have already posted this there, too: stackoverflow.com/q/55100453/6372809
– ilkkachu
Mar 13 at 14:57
1
@NikhileshSingh please be aware that cross-posting like this is a specific reason for getting your question closed - sometimes on both sites! If you ask a complex question in two different places at the same time, it can lead to duplicated effort. It is not very respectful. If you manage to cross-post the question without some necessary detail, which was present in the older question, that's not great either.
– sourcejedi
Mar 13 at 18:33
|
show 8 more comments
I am working on Linux kernel 4.19.2. I want to read performance counters available without using perf or any such tool.
From the userspace, I use code as follows.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
#define rdpmc(counter,low,high)
__asm__ __volatile__("rdpmc"
: "=a" (low), "=d" (high)
: "c" (counter))
void test()
printf(".");
static long
perf_event_open (struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
int ret;
ret = syscall (__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
return ret;
int
main ()
unsigned long values1, values2;
unsigned int fixed0, low, high;
struct perf_event_attr pe;
int fd, i;
fixed0 = (1 << 30);
memset (&pe, 0, sizeof (struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof (struct perf_event_attr);
pe.config = PERF_COUNT_HW_INSTRUCTIONS;
pe.disabled = 1;
pe.exclude_kernel = 0;
pe.exclude_user = 0;
pe.exclude_hv = 0;
pe.exclude_idle = 0;
fd = perf_event_open (&pe, 0, -1, -1, 0);
if (fd == -1)
fprintf (stderr, "Error opening leader %llxn", pe.config);
exit (EXIT_FAILURE);
for (i=1; i<=50; i++)
ioctl (fd, PERF_EVENT_IOC_RESET, 0);
ioctl (fd, PERF_EVENT_IOC_ENABLE, 0);
rdpmc (fixed0, low, high);
values1 = ((unsigned long) high << 32) + (unsigned long) low;
test();
rdpmc (fixed0, low, high);
values2 = ((unsigned long) high << 32) + (unsigned long) low;
ioctl (fd, PERF_EVENT_IOC_DISABLE, 0);
printf (" %lun", values2 );
close (fd);
Now I want to implement the same thing in the kernel code.
My goal is that, at every context switch get the count of an event and store it in the task structure. Hence eventually I want the counter to be called from the context_switch() function in the kernel. If I do it from the kernel then I will have the advantage of always running in the context of the current thread.
I think most of the code can be reused from the kernel as well.
I am not sure about the ioctl() part though.
linux linux-kernel
I am working on Linux kernel 4.19.2. I want to read performance counters available without using perf or any such tool.
From the userspace, I use code as follows.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
#define rdpmc(counter,low,high)
__asm__ __volatile__("rdpmc"
: "=a" (low), "=d" (high)
: "c" (counter))
void test()
printf(".");
static long
perf_event_open (struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
int ret;
ret = syscall (__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
return ret;
int
main ()
unsigned long values1, values2;
unsigned int fixed0, low, high;
struct perf_event_attr pe;
int fd, i;
fixed0 = (1 << 30);
memset (&pe, 0, sizeof (struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof (struct perf_event_attr);
pe.config = PERF_COUNT_HW_INSTRUCTIONS;
pe.disabled = 1;
pe.exclude_kernel = 0;
pe.exclude_user = 0;
pe.exclude_hv = 0;
pe.exclude_idle = 0;
fd = perf_event_open (&pe, 0, -1, -1, 0);
if (fd == -1)
fprintf (stderr, "Error opening leader %llxn", pe.config);
exit (EXIT_FAILURE);
for (i=1; i<=50; i++)
ioctl (fd, PERF_EVENT_IOC_RESET, 0);
ioctl (fd, PERF_EVENT_IOC_ENABLE, 0);
rdpmc (fixed0, low, high);
values1 = ((unsigned long) high << 32) + (unsigned long) low;
test();
rdpmc (fixed0, low, high);
values2 = ((unsigned long) high << 32) + (unsigned long) low;
ioctl (fd, PERF_EVENT_IOC_DISABLE, 0);
printf (" %lun", values2 );
close (fd);
Now I want to implement the same thing in the kernel code.
My goal is that, at every context switch get the count of an event and store it in the task structure. Hence eventually I want the counter to be called from the context_switch() function in the kernel. If I do it from the kernel then I will have the advantage of always running in the context of the current thread.
I think most of the code can be reused from the kernel as well.
I am not sure about the ioctl() part though.
linux linux-kernel
linux linux-kernel
edited Mar 13 at 13:11
Nikhilesh Singh
asked Mar 13 at 10:37
Nikhilesh SinghNikhilesh Singh
278
278
closed as unclear what you're asking by dirkt, sourcejedi, Mr Shunz, ilkkachu, Jeff Schaller♦ Mar 13 at 17:48
Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.
closed as unclear what you're asking by dirkt, sourcejedi, Mr Shunz, ilkkachu, Jeff Schaller♦ Mar 13 at 17:48
Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.
@sourcejedi This ioctl() would be calling something in the kernel right? I want to do it from there directly. Am I missing something here?
– Nikhilesh Singh
Mar 13 at 11:08
1
@NikhileshSingh I assume that doesn't crash, but your program does not explain unambiguously on its own. You are reading a per-cpu counter. You have not shown what your intention is v.s. Linux choosing to migrate your process between different cpus while it is running. Your english language description doesn't say anything about which CPU(s) you want counter values from either.
– sourcejedi
Mar 13 at 12:06
1
Also you still haven't explained why you think you can do the__NR_perf_event_open()
part from the kernel. Why are you confident about that part, but you need to ask aboutioctl()
? That would be a nice clear way to show "where you got stuck", and the specific answer you seem to be looking for.
– sourcejedi
Mar 13 at 12:10
1
I was going to suggest if this should have been on SO, but you seem to have already posted this there, too: stackoverflow.com/q/55100453/6372809
– ilkkachu
Mar 13 at 14:57
1
@NikhileshSingh please be aware that cross-posting like this is a specific reason for getting your question closed - sometimes on both sites! If you ask a complex question in two different places at the same time, it can lead to duplicated effort. It is not very respectful. If you manage to cross-post the question without some necessary detail, which was present in the older question, that's not great either.
– sourcejedi
Mar 13 at 18:33
|
show 8 more comments
@sourcejedi This ioctl() would be calling something in the kernel right? I want to do it from there directly. Am I missing something here?
– Nikhilesh Singh
Mar 13 at 11:08
1
@NikhileshSingh I assume that doesn't crash, but your program does not explain unambiguously on its own. You are reading a per-cpu counter. You have not shown what your intention is v.s. Linux choosing to migrate your process between different cpus while it is running. Your english language description doesn't say anything about which CPU(s) you want counter values from either.
– sourcejedi
Mar 13 at 12:06
1
Also you still haven't explained why you think you can do the__NR_perf_event_open()
part from the kernel. Why are you confident about that part, but you need to ask aboutioctl()
? That would be a nice clear way to show "where you got stuck", and the specific answer you seem to be looking for.
– sourcejedi
Mar 13 at 12:10
1
I was going to suggest if this should have been on SO, but you seem to have already posted this there, too: stackoverflow.com/q/55100453/6372809
– ilkkachu
Mar 13 at 14:57
1
@NikhileshSingh please be aware that cross-posting like this is a specific reason for getting your question closed - sometimes on both sites! If you ask a complex question in two different places at the same time, it can lead to duplicated effort. It is not very respectful. If you manage to cross-post the question without some necessary detail, which was present in the older question, that's not great either.
– sourcejedi
Mar 13 at 18:33
@sourcejedi This ioctl() would be calling something in the kernel right? I want to do it from there directly. Am I missing something here?
– Nikhilesh Singh
Mar 13 at 11:08
@sourcejedi This ioctl() would be calling something in the kernel right? I want to do it from there directly. Am I missing something here?
– Nikhilesh Singh
Mar 13 at 11:08
1
1
@NikhileshSingh I assume that doesn't crash, but your program does not explain unambiguously on its own. You are reading a per-cpu counter. You have not shown what your intention is v.s. Linux choosing to migrate your process between different cpus while it is running. Your english language description doesn't say anything about which CPU(s) you want counter values from either.
– sourcejedi
Mar 13 at 12:06
@NikhileshSingh I assume that doesn't crash, but your program does not explain unambiguously on its own. You are reading a per-cpu counter. You have not shown what your intention is v.s. Linux choosing to migrate your process between different cpus while it is running. Your english language description doesn't say anything about which CPU(s) you want counter values from either.
– sourcejedi
Mar 13 at 12:06
1
1
Also you still haven't explained why you think you can do the
__NR_perf_event_open()
part from the kernel. Why are you confident about that part, but you need to ask about ioctl()
? That would be a nice clear way to show "where you got stuck", and the specific answer you seem to be looking for.– sourcejedi
Mar 13 at 12:10
Also you still haven't explained why you think you can do the
__NR_perf_event_open()
part from the kernel. Why are you confident about that part, but you need to ask about ioctl()
? That would be a nice clear way to show "where you got stuck", and the specific answer you seem to be looking for.– sourcejedi
Mar 13 at 12:10
1
1
I was going to suggest if this should have been on SO, but you seem to have already posted this there, too: stackoverflow.com/q/55100453/6372809
– ilkkachu
Mar 13 at 14:57
I was going to suggest if this should have been on SO, but you seem to have already posted this there, too: stackoverflow.com/q/55100453/6372809
– ilkkachu
Mar 13 at 14:57
1
1
@NikhileshSingh please be aware that cross-posting like this is a specific reason for getting your question closed - sometimes on both sites! If you ask a complex question in two different places at the same time, it can lead to duplicated effort. It is not very respectful. If you manage to cross-post the question without some necessary detail, which was present in the older question, that's not great either.
– sourcejedi
Mar 13 at 18:33
@NikhileshSingh please be aware that cross-posting like this is a specific reason for getting your question closed - sometimes on both sites! If you ask a complex question in two different places at the same time, it can lead to duplicated effort. It is not very respectful. If you manage to cross-post the question without some necessary detail, which was present in the older question, that's not great either.
– sourcejedi
Mar 13 at 18:33
|
show 8 more comments
1 Answer
1
active
oldest
votes
Technically, it may be possible to call ioctl inside kernel code. It is called ksys_ioctl().[*] Notice how init/
is the only other code that calls ksys_ioctl(). This is an unusual thing to do, to put it mildly. Calling perf ioctls inside the kernel sounds even more dubious.
To start understanding why this is unusual, I would point out that ksys_ioctl()
still takes an fd
argument. This is the number of a file descriptor within the context of the current task (process/thread).
[edit] My goal is that, at every context switch get the count of an event and store it in the task structure. Hence eventually I want the counter to be called from the context_switch() function in the kernel.
AAAHHH.
So you did not want to call ioctl() from the kernel. (You would not have a file descriptor to call ioctl() on. And I do not believe you want to start opening file descriptors into the file table of the current task during every context_switch(). Even if you close them afterwards).
At this point, you are asking about implementing (a smaller version of) the Linux perf
sub-system. The perf
subsystem owns the performance counters. If you want to use the performance counters without the perf
subsystem, you should start by disabling perf
support in the kernel. At some later point in the process you should spend time looking at relevant material in the SDM (or related manuals - I have not checked which).
[*] Sidenote: there are limitations when you pass pointers into ksys_*()
functions. Basically they expect __user
memory, not kernel memory, unless you play games using set_fs()
..
Working on the perf
code would be a different matter. You can easily find the code to start looking at there, e.g. by clicking on PERF_EVENT_IOC_RESET . As well as the specific line, that will give you a source file (and directory) to look at, and you can also keep clicking around :-). Therefore I assume that is not your question.
perf does a lot of sampling and is quite complicated. I just want a mechanism to get some counter values while I am running in the context of a given thread. What do you exactly mean by compiling out perf code, as it's quite complicated.
– Nikhilesh Singh
Mar 13 at 19:04
1
@NikhileshSingh cateee.net/lkddb/web-lkddb/PERF_COUNTERS.html
– sourcejedi
Mar 13 at 19:05
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Technically, it may be possible to call ioctl inside kernel code. It is called ksys_ioctl().[*] Notice how init/
is the only other code that calls ksys_ioctl(). This is an unusual thing to do, to put it mildly. Calling perf ioctls inside the kernel sounds even more dubious.
To start understanding why this is unusual, I would point out that ksys_ioctl()
still takes an fd
argument. This is the number of a file descriptor within the context of the current task (process/thread).
[edit] My goal is that, at every context switch get the count of an event and store it in the task structure. Hence eventually I want the counter to be called from the context_switch() function in the kernel.
AAAHHH.
So you did not want to call ioctl() from the kernel. (You would not have a file descriptor to call ioctl() on. And I do not believe you want to start opening file descriptors into the file table of the current task during every context_switch(). Even if you close them afterwards).
At this point, you are asking about implementing (a smaller version of) the Linux perf
sub-system. The perf
subsystem owns the performance counters. If you want to use the performance counters without the perf
subsystem, you should start by disabling perf
support in the kernel. At some later point in the process you should spend time looking at relevant material in the SDM (or related manuals - I have not checked which).
[*] Sidenote: there are limitations when you pass pointers into ksys_*()
functions. Basically they expect __user
memory, not kernel memory, unless you play games using set_fs()
..
Working on the perf
code would be a different matter. You can easily find the code to start looking at there, e.g. by clicking on PERF_EVENT_IOC_RESET . As well as the specific line, that will give you a source file (and directory) to look at, and you can also keep clicking around :-). Therefore I assume that is not your question.
perf does a lot of sampling and is quite complicated. I just want a mechanism to get some counter values while I am running in the context of a given thread. What do you exactly mean by compiling out perf code, as it's quite complicated.
– Nikhilesh Singh
Mar 13 at 19:04
1
@NikhileshSingh cateee.net/lkddb/web-lkddb/PERF_COUNTERS.html
– sourcejedi
Mar 13 at 19:05
add a comment |
Technically, it may be possible to call ioctl inside kernel code. It is called ksys_ioctl().[*] Notice how init/
is the only other code that calls ksys_ioctl(). This is an unusual thing to do, to put it mildly. Calling perf ioctls inside the kernel sounds even more dubious.
To start understanding why this is unusual, I would point out that ksys_ioctl()
still takes an fd
argument. This is the number of a file descriptor within the context of the current task (process/thread).
[edit] My goal is that, at every context switch get the count of an event and store it in the task structure. Hence eventually I want the counter to be called from the context_switch() function in the kernel.
AAAHHH.
So you did not want to call ioctl() from the kernel. (You would not have a file descriptor to call ioctl() on. And I do not believe you want to start opening file descriptors into the file table of the current task during every context_switch(). Even if you close them afterwards).
At this point, you are asking about implementing (a smaller version of) the Linux perf
sub-system. The perf
subsystem owns the performance counters. If you want to use the performance counters without the perf
subsystem, you should start by disabling perf
support in the kernel. At some later point in the process you should spend time looking at relevant material in the SDM (or related manuals - I have not checked which).
[*] Sidenote: there are limitations when you pass pointers into ksys_*()
functions. Basically they expect __user
memory, not kernel memory, unless you play games using set_fs()
..
Working on the perf
code would be a different matter. You can easily find the code to start looking at there, e.g. by clicking on PERF_EVENT_IOC_RESET . As well as the specific line, that will give you a source file (and directory) to look at, and you can also keep clicking around :-). Therefore I assume that is not your question.
perf does a lot of sampling and is quite complicated. I just want a mechanism to get some counter values while I am running in the context of a given thread. What do you exactly mean by compiling out perf code, as it's quite complicated.
– Nikhilesh Singh
Mar 13 at 19:04
1
@NikhileshSingh cateee.net/lkddb/web-lkddb/PERF_COUNTERS.html
– sourcejedi
Mar 13 at 19:05
add a comment |
Technically, it may be possible to call ioctl inside kernel code. It is called ksys_ioctl().[*] Notice how init/
is the only other code that calls ksys_ioctl(). This is an unusual thing to do, to put it mildly. Calling perf ioctls inside the kernel sounds even more dubious.
To start understanding why this is unusual, I would point out that ksys_ioctl()
still takes an fd
argument. This is the number of a file descriptor within the context of the current task (process/thread).
[edit] My goal is that, at every context switch get the count of an event and store it in the task structure. Hence eventually I want the counter to be called from the context_switch() function in the kernel.
AAAHHH.
So you did not want to call ioctl() from the kernel. (You would not have a file descriptor to call ioctl() on. And I do not believe you want to start opening file descriptors into the file table of the current task during every context_switch(). Even if you close them afterwards).
At this point, you are asking about implementing (a smaller version of) the Linux perf
sub-system. The perf
subsystem owns the performance counters. If you want to use the performance counters without the perf
subsystem, you should start by disabling perf
support in the kernel. At some later point in the process you should spend time looking at relevant material in the SDM (or related manuals - I have not checked which).
[*] Sidenote: there are limitations when you pass pointers into ksys_*()
functions. Basically they expect __user
memory, not kernel memory, unless you play games using set_fs()
..
Working on the perf
code would be a different matter. You can easily find the code to start looking at there, e.g. by clicking on PERF_EVENT_IOC_RESET . As well as the specific line, that will give you a source file (and directory) to look at, and you can also keep clicking around :-). Therefore I assume that is not your question.
Technically, it may be possible to call ioctl inside kernel code. It is called ksys_ioctl().[*] Notice how init/
is the only other code that calls ksys_ioctl(). This is an unusual thing to do, to put it mildly. Calling perf ioctls inside the kernel sounds even more dubious.
To start understanding why this is unusual, I would point out that ksys_ioctl()
still takes an fd
argument. This is the number of a file descriptor within the context of the current task (process/thread).
[edit] My goal is that, at every context switch get the count of an event and store it in the task structure. Hence eventually I want the counter to be called from the context_switch() function in the kernel.
AAAHHH.
So you did not want to call ioctl() from the kernel. (You would not have a file descriptor to call ioctl() on. And I do not believe you want to start opening file descriptors into the file table of the current task during every context_switch(). Even if you close them afterwards).
At this point, you are asking about implementing (a smaller version of) the Linux perf
sub-system. The perf
subsystem owns the performance counters. If you want to use the performance counters without the perf
subsystem, you should start by disabling perf
support in the kernel. At some later point in the process you should spend time looking at relevant material in the SDM (or related manuals - I have not checked which).
[*] Sidenote: there are limitations when you pass pointers into ksys_*()
functions. Basically they expect __user
memory, not kernel memory, unless you play games using set_fs()
..
Working on the perf
code would be a different matter. You can easily find the code to start looking at there, e.g. by clicking on PERF_EVENT_IOC_RESET . As well as the specific line, that will give you a source file (and directory) to look at, and you can also keep clicking around :-). Therefore I assume that is not your question.
edited Mar 13 at 19:01
answered Mar 13 at 11:28
sourcejedisourcejedi
25.9k445113
25.9k445113
perf does a lot of sampling and is quite complicated. I just want a mechanism to get some counter values while I am running in the context of a given thread. What do you exactly mean by compiling out perf code, as it's quite complicated.
– Nikhilesh Singh
Mar 13 at 19:04
1
@NikhileshSingh cateee.net/lkddb/web-lkddb/PERF_COUNTERS.html
– sourcejedi
Mar 13 at 19:05
add a comment |
perf does a lot of sampling and is quite complicated. I just want a mechanism to get some counter values while I am running in the context of a given thread. What do you exactly mean by compiling out perf code, as it's quite complicated.
– Nikhilesh Singh
Mar 13 at 19:04
1
@NikhileshSingh cateee.net/lkddb/web-lkddb/PERF_COUNTERS.html
– sourcejedi
Mar 13 at 19:05
perf does a lot of sampling and is quite complicated. I just want a mechanism to get some counter values while I am running in the context of a given thread. What do you exactly mean by compiling out perf code, as it's quite complicated.
– Nikhilesh Singh
Mar 13 at 19:04
perf does a lot of sampling and is quite complicated. I just want a mechanism to get some counter values while I am running in the context of a given thread. What do you exactly mean by compiling out perf code, as it's quite complicated.
– Nikhilesh Singh
Mar 13 at 19:04
1
1
@NikhileshSingh cateee.net/lkddb/web-lkddb/PERF_COUNTERS.html
– sourcejedi
Mar 13 at 19:05
@NikhileshSingh cateee.net/lkddb/web-lkddb/PERF_COUNTERS.html
– sourcejedi
Mar 13 at 19:05
add a comment |
@sourcejedi This ioctl() would be calling something in the kernel right? I want to do it from there directly. Am I missing something here?
– Nikhilesh Singh
Mar 13 at 11:08
1
@NikhileshSingh I assume that doesn't crash, but your program does not explain unambiguously on its own. You are reading a per-cpu counter. You have not shown what your intention is v.s. Linux choosing to migrate your process between different cpus while it is running. Your english language description doesn't say anything about which CPU(s) you want counter values from either.
– sourcejedi
Mar 13 at 12:06
1
Also you still haven't explained why you think you can do the
__NR_perf_event_open()
part from the kernel. Why are you confident about that part, but you need to ask aboutioctl()
? That would be a nice clear way to show "where you got stuck", and the specific answer you seem to be looking for.– sourcejedi
Mar 13 at 12:10
1
I was going to suggest if this should have been on SO, but you seem to have already posted this there, too: stackoverflow.com/q/55100453/6372809
– ilkkachu
Mar 13 at 14:57
1
@NikhileshSingh please be aware that cross-posting like this is a specific reason for getting your question closed - sometimes on both sites! If you ask a complex question in two different places at the same time, it can lead to duplicated effort. It is not very respectful. If you manage to cross-post the question without some necessary detail, which was present in the older question, that's not great either.
– sourcejedi
Mar 13 at 18:33