MSR (Model-Specific Register) control 21 Jan 1999 Richard Gooch MSRs provide access to internal processor functions and allow you to control the behaviour of the processor. While the set of MSRs is highly model-dependent, there is a reasonably generic interface which may be used to read and write these registers. The CONFIG_MSR option allows you to compile the device driver which provides access to these registers from user space. The driver creates the /dev/cpu/msr device file. By using ioctl() functions on this device you can read and write specified MSRs. A separate user space library is available from: http://www.atnf.csiro.au/~rgooch/linux/ which mimics the MSR interface available in kernel space. This makes it very easy to write code which manipulates MSRs, as all code development can be done from userspace. Once the code has been developed and tested, it can be incorporated into a kernel device driver with very few changes. Apart from being more convenient, it is also safer, as you can write your code without worring about generating an Oops, a Panic or generally messing with kernel data structures. There is one caveat, however: if you incorrectly programme a MSR, the behaviour of the processor is undefined. At best, your programme will fail as you try to write to an undefined MSR. At worst, you could trigger an internal fault and cause the processor to cook itself. That said, chances are the worst will not happen, because modern processors should not do anything harmful to themselves, no matter how they are programmed. But you have been warned: carry on at your own risk. =============================================================================== Performance monitoring interface control 21 Jan 1999 Richard Gooch Many processors provide special Performance Monitoring Counters (PMCs) for the purposes of system or application tuning. You can usually count mundane events such as the number of floating point multiplies, to more exotic events such as the number of cache misses when reading data. If you have a programme which is not running as fast as you expected, performance monitoring can provide useful insights. The CONFIG_PERFMON option allows you to compile the device driver which provides a slightly simplified interface to these features. The driver creates the /dev/cpu/perfmon%u device files (one file per performance counter). In general, you can also gain access to these facilities using the interface created by CONFIG_MSR, but that interface is harder to use and buggy programmes using it are more likely to crash your machine. Because this is a cruel world, the kinds of events you can monitor vary greatly from one model processor to another. This interface tries to make no assumptions about the kinds of events supported, it just provides a generic interface for selecting which events are to be counted and easy access to the counters themselves. It is up to the programmer to know which event codes are available for different model processors. If you read one of the device files, the current counter value is output in ASCII hexadecimal format. A set of ioctl() operations allows you to select which event a counter will count. The counters can operate in one of two modes: "global" (or basic) and "virtual" (or per-process). In global mode, the PMCs count events for all processes on the system. On a system which is idle except for the application you wish to monitor, this is the easiest mode of operation. On a busy system, you may wish to consider enabling virtual mode. In this mode, each process (or thread) has it's own set of private (virtual) PMCs, which are saved and restored across context switches. Naturally, when you read the device files you only see the PMCs for the reading process and not an aggregate of the whole system. If you wish to inspect the PMCs of another process, you need to use the ptrace(2) interface. Note that the same type of event is counted for all processes for each PMC. NOTE: VIRTUAL MODE IS NOT YET IMPLEMENTED. A separate user space library is available from: http://www.atnf.csiro.au/~rgooch/linux/ which provides a simple and convenient interface to the device driver. In addition, header files are provided which have symbolic definitions for the event codes for some processor models.