Hi all,
when running parsec dedup benchmark in SE mode (gem5-stable, x86 simple
timing + ruby MESI_CMP_directory), the simulation ends: "Ruby functional
read failed" error.
Digging into protocol traces I've found two cpu trying modify the same cache
block, data was just sent from L1 to L2, while a third cpu tried to access
the same block using functional read initiated by a syscall. So the only
valid data block cannot be found in any cache controller, because it is in
the message queued to be delivered to the L2 , as it is described in the
communication two years ago.
This bug is easy reproducible using attached code.

As it was already mentioned in the mailing list, the right solution should
be to inspect all queued packets and to find the message containing the data
block (in the RubySystem::functionalRead implementation in
src/mem/ruby/system/System.cc).  
But as I don't know how to find all queues and packets, I've implemented
this workaround: 

Every DataBlk in any message is registered in a circular buffer before the
message is enqueued ("enqueue generate" in slicc).
Then the data can be found and read by RubySystem::functionalRead even
though they are not available in controllers.

I tried to put changes to a repository (changesets 10006:7a645dc20a80 and
10007:d9d8bb691e64), but I don't know if they are correctly submited. Sorry,
I've never worked with versioning sw before. Can I ask for help with it ? 

Regards,
Jiri Kaspar

BTW, in the scenario above, the functionalWrite will not work correctly,
data updated by functionalWrite in controllers will be replaced with old
data from a queued packet several ticks later.

-----------------------------------------------
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h> 

char buffer[32] = "123456789012345678901234567890";
char *cnt = &buffer[0];
long long ii;

void* counter(void *arg) {
  for (;;) __sync_fetch_and_add(cnt,1);
}

int main(int argc, char **argv) {
  pthread_t thread[2];
  if ( pthread_create(&thread[0], NULL, counter, (void *) &ii) != 0 ) {
        printf("pthread_create() error");
        exit(1);
  }
  if ( pthread_create(&thread[1], NULL, counter, (void *) &ii) != 0 ) {
        printf("pthread_create() error");
        exit(1);
  }
  for (;;) {
    FILE *f;
    f = fopen(&buffer[1],"r");
  }
}


_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to