void init_buffer() { int i; int j, flag; cc_cacheregn_t regn; int *p; buffer = malloc(sizeof(int)*num_sets*ways*linesize); printf(" allocating a total of %ldMB \n",sizeof(int)*num_sets*ways*linesize/(1024*1024)); // insert ulcc here data_start = (int *)ULCC_ALIGN_HIGHER((unsigned long)buffer); data_end = (int *)ULCC_ALIGN_LOWER((unsigned long)(buffer+(sizeof(int)*num_sets*ways*linesize))); cc_cacheregn_clr(®n); cc_cacheregn_set(®n, color_low, color_high, 1); if(cc_remap((unsigned long *)&data_start, (unsigned long *)&data_end, 1, ®n, CC_ALLOC_NOMOVE | CC_MAPORDER_SEQ) < 0) { fprintf(stderr, "failed to remap data region 1\n"); return; } //printf("%d\n",*data_end); srand(time(NULL)); p=(int *)buffer; for(p = (int *)data_start; p<(int *)data_end; p++) { *p = (rand()%128); } }
int _ULCC_HIDDEN _nr_aligned_pages(const unsigned long *start, const unsigned long *end, const int n) { int nr_pages = 0; int i, delta; for(i = 0; i < n; i++) { delta = (ULCC_ALIGN_LOWER(end[i]) - ULCC_ALIGN_HIGHER(start[i])) / ULCC_PAGE_BYTES; nr_pages += delta < 0 ? 0 : delta; } return nr_pages; }
int _ULCC_HIDDEN _remap_pages_arb( struct _page_picker_s *picker, const unsigned long *start, const unsigned long *end, const int n, char *do_remap, const int movedata) { void *remap_to, *remap_to_end, *remap_from; int idr, i_remap = 0, i_picked = 0; int ret = 0; for(idr = 0; idr < n; idr++) { remap_to = (void *)ULCC_ALIGN_HIGHER(start[idr]); remap_to_end = (void *)ULCC_ALIGN_LOWER(end[idr]); while(remap_to < remap_to_end) { if(!do_remap[i_remap++]) { remap_to += ULCC_PAGE_BYTES; continue; } remap_from = picker[0].pages[i_picked++]; if(movedata) memcpy(remap_from, remap_to, ULCC_PAGE_BYTES); /* Remap the picked physical page to user data region */ if(mremap(remap_from, ULCC_PAGE_BYTES, ULCC_PAGE_BYTES, MREMAP_MAYMOVE | MREMAP_FIXED, remap_to) == MAP_FAILED) { _ULCC_PERROR("mremap failed in _remap_pages_arb"); ret = -1; goto finish; } /* Repair the page hole caused by the above remapping */ if(mmap(remap_from, ULCC_PAGE_BYTES, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, 0, 0) != remap_from) { _ULCC_PERROR("mmap failed in _remap_pages_arb"); ret = -1; goto finish; } remap_to += ULCC_PAGE_BYTES; } } /* For each data region */ finish: return ret; }
/* Note: if no colors are set in cacheregn, then all pages will be considered * to need remapping */ int _ULCC_HIDDEN _pages_to_be_remapped( const unsigned long *start, const unsigned long *end, const int n, const cc_cacheregn_t *regn, char *do_remap) { int nr_pages = 0, c_pages; cc_uint64_t *pfnbuf = NULL; char *colors_inc = NULL; int i, j; /* Get the colors specified in the cache region */ colors_inc = malloc(sizeof(*colors_inc) * ULCC_NR_CACHE_COLORS); if(!colors_inc) return -1; for(i = 0; i < ULCC_NR_CACHE_COLORS; i++) if(ULCC_TST_COLOR_BIT(regn, i)) colors_inc[i] = 1; else colors_inc[i] = 0; /* Allocate page frame number buffer for address translation */ c_pages = 0; for(i = 0; i < n; i++) { nr_pages = (ULCC_ALIGN_LOWER(end[i]) - ULCC_ALIGN_HIGHER(start[i])) / ULCC_PAGE_BYTES; if(nr_pages > c_pages) c_pages = nr_pages; } pfnbuf = malloc(sizeof(*pfnbuf) * c_pages); if(!pfnbuf) { _ULCC_PERROR("malloc for pfnbuf failed in _pages_to_be_remapped"); free(colors_inc); return -1; } /* Pages unpresent or whose colors are not included in desired colors need * to be remapped */ c_pages = 0; /* c_pages will equal the number of pages to be remapped */ for(i = 0; i < n; i++) { nr_pages = (ULCC_ALIGN_LOWER(end[i]) - ULCC_ALIGN_HIGHER(start[i])) / ULCC_PAGE_BYTES; if(nr_pages <= 0) continue; if(cc_addr_translate(pfnbuf, ULCC_ALIGN_HIGHER(start[i]), nr_pages) < 0) { free(pfnbuf); free(colors_inc); return -1; } for(j = 0; j < nr_pages; j++) { if(cc_pfn_present(pfnbuf[j]) && colors_inc[cc_pfn_color(pfnbuf[j])]) do_remap[j] = 0; /* need no remapping */ else { do_remap[j] = 1; /* need remapping */ c_pages++; } } do_remap += nr_pages; } free(pfnbuf); free(colors_inc); return c_pages; }
int _ULCC_HIDDEN _remap_pages_rand( struct _page_picker_s *picker, const unsigned long *start, const unsigned long *end, const int n, char *do_remap, const int movedata) { void *remap_to, *remap_to_end, *remap_from; int c_colors = 0, i_remap = 0, i, idr; int *index = NULL; unsigned int rand_seed; int ret = 0; index = malloc(sizeof(*index) * ULCC_NR_CACHE_COLORS); if(!index) { _ULCC_PERROR("failed to malloc for index array in _remap_pages_seq"); ret = -1; goto finish; } /* Compute the number of colors in this request and build index array */ for(i = 0; i < ULCC_NR_CACHE_COLORS; i++) if(picker[i].needed > 0) index[c_colors++] = i; _ULCC_ASSERT(c_colors > 0); rand_seed = time(NULL); /* For each data region, do the remapping */ for(idr = 0, i = 0; idr < n; idr++) { remap_to = (void *)ULCC_ALIGN_HIGHER(start[idr]); remap_to_end = (void *)ULCC_ALIGN_LOWER(end[idr]); while(remap_to < remap_to_end) { if(!do_remap[i_remap++]) { remap_to += ULCC_PAGE_BYTES; continue; } /* Get the next picked page to remap from */ i = (i + rand_r(&rand_seed)) % c_colors; while(picker[index[i]].picked == 0) i = (i + 1) % c_colors; remap_from = picker[index[i]].pages[--picker[index[i]].picked]; /* Copy data before remapping if required so */ if(movedata) memcpy(remap_from, remap_to, ULCC_PAGE_BYTES); /* Remap the picked physical page to user data page */ if(mremap(remap_from, ULCC_PAGE_BYTES, ULCC_PAGE_BYTES, MREMAP_MAYMOVE | MREMAP_FIXED, remap_to) == MAP_FAILED) { _ULCC_PERROR("mremap failed in _remap_pages_rand"); ret = -1; goto finish; } /* Repair the page hole caused by the above remapping */ if(mmap(remap_from, ULCC_PAGE_BYTES, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, 0, 0) != remap_from) { _ULCC_PERROR("mmap failed in _remap_pages_rand"); ret = -1; goto finish; } remap_to += ULCC_PAGE_BYTES; } /* while */ } /* for each data region */ finish: if(index) free(index); return ret; }
int _ULCC_HIDDEN _remap_pages_seq( struct _page_picker_s *picker, const unsigned long *start, const unsigned long *end, const int n, char *do_remap, const int movedata) { void *remap_from, *remap_to, *remap_to_end; int c_colors = 0, i_remap = 0, i, idr; int *index = NULL; int ret = 0; index = malloc(sizeof(*index) * ULCC_NR_CACHE_COLORS); if(!index) { _ULCC_PERROR("failed to malloc for index array in _remap_pages_seq"); ret = -1; goto finish; } /* Compute the number of colors in this request and build index array */ for(i = 0; i < ULCC_NR_CACHE_COLORS; i++) if(picker[i].needed > 0) index[c_colors++] = i; _ULCC_ASSERT(c_colors > 0); /* For each data region, do the remapping */ for(idr = 0, i = 0; idr < n; idr++) { remap_to = (void *)ULCC_ALIGN_HIGHER(start[idr]); remap_to_end = (void *)ULCC_ALIGN_LOWER(end[idr]); while(remap_to < remap_to_end) { /* If this page does not need to be remapped, skip it */ if(!do_remap[i_remap++]) { remap_to += ULCC_PAGE_BYTES; continue; } /* Get the next picked page to remap from. * Infinite looping is guaranteed not to happen as long as the total * amount of picked pages is not fewer than required, which is true * after _pick_pages successfully returned. */ while(picker[index[i]].picked <= 0) i = (i + 1) % c_colors; /* Select a page to remap from. * A possible problem with remapping from tail to head is that the * number of continuous physical pages in the virtual memory area * being remapped to will decrease. Consider to remap from head to * tail. */ remap_from = picker[index[i]].pages[--picker[index[i]].picked]; /* Copy data before remapping if required so */ if(movedata) memcpy(remap_from, remap_to, ULCC_PAGE_BYTES); /* Remap the picked physical page to user data page; this is one * of the key hacks to user-level cache control */ if(mremap(remap_from, ULCC_PAGE_BYTES, ULCC_PAGE_BYTES, MREMAP_MAYMOVE | MREMAP_FIXED, remap_to) == MAP_FAILED) { _ULCC_PERROR("mremap failed in _remap_pages_seq"); ret = -1; goto finish; } /* Repair the page hole caused by the above remapping; this is one * of the key hacks to user-level cache control */ if(mmap(remap_from, ULCC_PAGE_BYTES, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, 0, 0) != remap_from) { _ULCC_PERROR("mmap failed in _remap_pages_seq"); ret = -1; goto finish; } remap_to += ULCC_PAGE_BYTES; i = (i + 1) % c_colors; } /* while */ } /* for each data region */ finish: if(index) free(index); return ret; }