Subject: kernel->userland r/o page mapping
To: None <tech-kern@netbsd.org>
From: Matthew Mondor <mm_lists@pulsar-zone.net>
List: tech-kern
Date: 03/08/2007 07:45:52
--Multipart_Thu__8_Mar_2007_07_45_52_-0500_dV3w_9G55XMQkscc
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
For some applications I noticed that it would be useful to have minor
live kernel information bits accessible efficiently in userland in
read-only mode. For instance a new structure could be defined and some
userland library functions could obtain a pointer to it in the process
vm space to access the fields, unprivileged and efficiently.
Since I'm not familiar much with uvm it raised the following questions:
Is there currently in place a subsystem doing this which can be expanded
as needed? If not:
If init_main.c allocated a wired kernel physical page and mapped it in
init(8)'s virtual space as a wired, read-only, inheritable page, how
would userland reliably know at which address the page was mapped to,
without a new syscall? Perhaps throuh sysctl? Or if a specific address
had to be decided on, would there be an arch-independent address that
would suit this? Would using "page 0" for this be out of the question?
An alternative would possibly be a new device, say krtm(4) with only
mmap support, allowing any users to obtain the read-only mapping to the
wired kernel page. Unless I'm mistaken, other than initial
open(2)/mmap(2) overhead, accesses to the fields in memory would then
theoretically be at the same speed as with the previous method?
I could see various users of this such as to access the current time
faster. I guess that a process-specific page in a similar manner would
allow more real-time access of process statistics also, but probably
with the first method rather than through a device, the kernel updating
those statistics into the special page...
Thanks
--
Matt
--Multipart_Thu__8_Mar_2007_07_45_52_-0500_dV3w_9G55XMQkscc
Content-Type: application/octet-stream; name=clocktests.txt
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=clocktests.txt
$ time ./clocktest1 1000000
8.35s real 0.52s user 7.81s system
$ time ./clocktest2 1000000
8.50s real 0.52s user 7.96s system
$ time ./clocktest3 1000000
3.40s real 0.29s user 3.09s system
#include <sys/time.h>
#include <stdlib.h>
int main(int, char **);
int
main(int argc, char **argv)
{
int i, t;
if (argc != 2)
return EXIT_FAILURE;
t = atoi(argv[1]);
for (i = 0; i < t; i++) {
struct timeval tv;
(void) gettimeofday(&tv, NULL);
}
return EXIT_SUCCESS;
}
#include <stdlib.h>
#include <time.h>
int main(int, char **);
int
main(int argc, char **argv)
{
int i, t;
if (argc != 2)
return EXIT_FAILURE;
t = atoi(argv[1]);
for (i = 0; i < t; i++) {
struct timespec ts;
(void) clock_gettime(CLOCK_REALTIME, &ts);
}
return EXIT_SUCCESS;
}
#include <sys/param.h>
#include <sys/sysctl.h>
#include <stdlib.h>
int main(int, char **);
int
main(int argc, char **argv)
{
int i, t;
int mib[2];
size_t l;
mib[0] = CTL_KERN;
mib[1] = KERN_HARDCLOCK_TICKS;
l = sizeof(int);
if (argc != 2)
return EXIT_FAILURE;
t = atoi(argv[1]);
for (i = 0; i < t; i++) {
int c;
(void) sysctl(mib, 2, &c, &l, NULL, 0);
}
return EXIT_SUCCESS;
}
--Multipart_Thu__8_Mar_2007_07_45_52_-0500_dV3w_9G55XMQkscc--