On Thu, Apr 27, 2000 at 04:58:03PM +0200, Florian Lohoff wrote:
> i had a conversation with Harald concerning a "strong" time drift
> on my R4000 Decstation. He than was astonished on the large
> number of VCE.
> On a medium loaded machine i see 40-50 VCEDs per second.
VCE isn't related to timekeeping and only may delay interrupts minimally;
they're very lightweight. In fact keeping the VCE statistics makes a
significant part of the overhead. So while the number of VCEs may look
high the total price is not too bad.
> As a resume - The exception is taken when the index of the 1st and
> the 2nd level cache are not identical - Right ?
> So - why is there a mismatch ? Might it be due to some invalidation
> of the 1st (and not the 2nd) level cache ?
>
> As the exception is taken quiet often and the "Mips Risc Architecture" states
> "Software can avoid the cost of this trap by using constistent virtual
> primary cache indexes to access the same physical data".
Attached a small test program that generates a large number of vced exceptions.
It's causing aliases with the page cache and these are not covered by my
patch.
> Currently i dont think whats the exact cause of this exception and
> a probably optimization which brings this down.
The easiest part of the solution is choosing apropriate addresses for all
memory mappings without forced addresses, that is mmap(2) and mmap2(2)
without MAP_FIXED. A patch which fixes this part of the problem is attached.
This patch does not fix other types of aliases like mmap(2) and mmap2(2)
with MAP_FIXED or aliases between multiple mappings out of the page cache.
Users of R2000 / R3000 / R7000 / R10000 CPUs can ignore this whole thread,
those CPUs don't have such incredibly f*cked caches.
Ralf
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#define TESTFILE "hurz"
int main(int argc, char *argv[])
{
char template[] = "/tmp/mmap-XXXXXX";
int fd, res, i;
char *addr1, *addr2;
fd = mkstemp(template);
if (fd < 0) {
perror("Opening testfile failed");
exit(EXIT_FAILURE);
}
unlink(template);
res = write(fd, "x", 1);
if (res < 0) {
perror("Write failed");
exit(EXIT_FAILURE);
}
addr1 = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (addr1 == MAP_FAILED) {
perror("Mapping file failed");
}
addr2 = mmap(addr1 + 4096, 4096, PROT_READ|PROT_WRITE,
MAP_SHARED | MAP_FIXED, fd, 0);
if (addr2 == MAP_FAILED) {
perror("Mapping file at alias address failed");
}
for (i = 100000000; i; i--) {
* (volatile char *) addr1 = 1;
* (volatile char *) addr2 = 2;
}
exit(EXIT_SUCCESS);
}