I need to swap out specific pages of an ipc shared memory segment. I
used to modify the routine shm_swap() in file ipc/shm.c for this. The
modifications involved changing the segment and page selection code, so
the new routine would operate on intended pages.
In recent kernel versions shm_swap has changed considerably. A lot of
the iteration code (and also the flush_cache_page() and flush_tlb_page())
has disappeared. I still tried to get the same effects by modifying
shm_swap, but failed.
Is am providing the code I have tentatively written (and does not work).
What should be done to make it work?
Any help is appreciated.
-Kamran
/* this routine swaps out relevant parts of a shared memory. This was
constructed by doing some cut and paste on shm_swap. I hope this is
done the right way!
Depending on the value of dipc_page_size, we may want to swap out more
than one page.
id: determines the shared memory segment
offset: is an address in the page we want to swap out. We may want to swap
out the whole segment, in which case we ignore this value
mode: tell the routine if we want to swap out the whole segment
*/
int dipc_swap_out (int id, int offset, int mode)
{
pte_t page;
struct shmid_kernel *shp;
struct vm_area_struct *shmd=NULL;
unsigned int swap_nr;
unsigned long idx;
int start, end;
/**printk("dipc_swap_out(%d, %d, %d)\n",id, offset, mode);*/
shp = shm_segs[id];
/* no regard for locked shared memories! */
if(shp == IPC_UNUSED || shp == IPC_NOID)
return DIPC_FAIL;
if(mode == SEGMENT) {
start = 0;
end = shp->shm_npages;
}
else {
start = offset / PAGE_SIZE;
start = start - start % (dipc_page_size / PAGE_SIZE);
end = start + dipc_page_size / PAGE_SIZE;
if(end > shp->shm_npages)
end = shp->shm_npages;
}
for(idx = start; idx < end; idx++) {
if(!(swap_nr = get_swap_page()))
return DIPC_FAIL;
page = __pte(shp->shm_pages[idx]);
if (!pte_present(page))
continue;
/* don't have access to gfp_mask arg */
/*if ((gfp_mask & __GFP_DMA) && !PageDMA(&mem_map[MAP_NR(pte_page(page))]))
goto check_table;*/
swap_attempts++;
/*if (--counter < 0) {
failed:
swap_free (swap_nr);
return 0;
}*/
/*if (atomic_read(&mem_map[MAP_NR(pte_page(page))].count) != 1)
goto check_table;*/
shp->shm_pages[idx] = swap_nr;
rw_swap_page_nocache (WRITE, swap_nr, (char *) pte_page(page));
free_page(pte_page(page));
swap_successes++;
shm_swp++;
shm_rss--;
} /* for idx ... */
return DIPC_SUCCESS;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/