Emanuele Altieri, Hampshire College
(homepage)
Dominique Thiebaut, Smith College
(homepage)
December 2001
NOTE: The source code presented in this web page has been
tested on a Linux RedHat 7.0, kernel 2.2.16-22. If you have any
problem compiling on other distributions or kernels, feel free to
email ealtieri@hampshire.edu.
The source code is available here and is organized into the following directories:
msr/dev
- contains the MSR Device Drivermsr/include
- contains different MSR implementations for various processorsmsr/monitor
- contains tools to monitor programsmsr/test
- examples on how to use the device drivermsr/profiles
- examples of profiles generated by our tool
Each of these directories contains its own makefile. However,
the msr directory contains itself a general makefile
which will build everything.
The syntax of this makefile is the following:
$ make <module>
where module is the module that implements the MSR interface for a specific processor. A list of modules is available here
The make command will build the MSR Device Driver,
the appropriate MSR Module and the monitor tools.
This directory contains the source code of our MSR Device Driver
(msr.c and msr.h).
To build the device driver type
$ make module
where module is the module that implements the MSR interface for a specific processor. A list of modules is available here
The makefile will build the kernel module msr.o.
To load the device driver, log in as root and type the following command:
$ insmod msr.o
Then check the system log to see if the device driver has been registered:
$ tail /var/log/messages
....
....
....
Jun 14 14:42:14 ozventures kernel: msr: the module has been registered with major number 254
The major number assigned to the device is 254, in the example above. The OS dynamically assigns a major number to the device every time the driver is loaded, but if you wish you can select a specific major number by typing:
$ insmod msr.o msr_module_major=xxx
where xxx is a number between 1 and 254. Again, check
/var/log/messages or /proc/devices to
see if the module has been loaded. If the major number is already
in use by some other kernel module, then the device driver cannot
be loaded.
NOTE: the device driver checks the processor architecture to see if it matches the interface which the driver has been built for. If not, then the device driver cannot be loaded and an error message is sent to the system log.
Once the kernel module has been loaded, you need to create a node
for it in the /dev directory:
$ mknod /dev/msr c 254 0
where "/dev/msr" is the name of the node to be created,
"c" stands for character device, "254"
is the device major number and "0" the minor number.
You may also change the attributes of the node so that any user
applicaton can access the MSR Device Driver:
$ chmod a+rw /dev/msr
To unload the kernel module, type:
$ rmmod msr
Once the kernel module has been loaded, the read()
and write() file operations can be used to
access the model specific registers. These file operations
still take a file descriptor, a pointer and a counter as parameters,
but the device driver reinterprets these parameters as following:
ssize_t read(int msr_fd, struct MSR* value, msr_t reg);
ssize_t write(int msr_fd, struct MSR* value, msr_t reg);
where msr_fd is the file descriptor for the
device driver, value is an MSR structure
containing the value of the model specific register, and
reg is the MSR register to be read/written.
However, when accessing performance monitoring registers, it's reccomended to use the MSR modules, described in the following section.
This directory contains the MSR modules. An MSR module implements performance-monitoring MSR operations on a particular processor. All of the modules provide the same, processor-indipendent interface (MSR Interface), while the processor-specific implementation of this interface is hidden in the module's body. Therefore, these modules can be exchanged without having to modify the code of the application that is using them.
The MSR Interface, defined in msrio.h, consists of
the following operations:
The MSR Interface is automatically included in a program by
including the file msr.h, which, in addition,
links to the MSR Symbols of a specific processor.
Following is a list of the MSR modules that have been implemented so far:
| MODULE | PROCESSOR | Implementation | GCC Symbol |
| pentium.o | Intel Pentium | pentium.h, pentium.c | __INTEL_P0__ |
| pentium_mmx.o | Intel Pentium MMX | pentium_mmx.h, pentium_mmx.c | __INTEL_PMMX__ |
To build an MSR module:
$ make module
This directory contains tools for monitoring programs:
monitor creates a profile of the programtrace reads the profile generated by
monitor and outputs it to a text fileinvcache writes back and invalidates the cache
msr/Makefile
msr/interfaces.txt
msr/dev/Makefile
msr/dev/msr.h
msr/dev/msr.c
msr/dev/msr.o
msr/include/Makefile
msr/include/msrio.h
msr/include/msr.h
msr/include/pentium.h
msr/include/pentium.c
msr/include/pentium.o
msr/monitor/Makefile
msr/monitor/monitor.h
msr/monitor/monitor.c
msr/monitor/buffer.h
msr/monitor/error.h
msr/monitor/error.c
msr/monitor/sync.h
msr/monitor/sync.c
msr/monitor/monitor