/* * Attempt to steal a page from a pipe buffer. This should perhaps go into * a vm helper function, it's already simplified quite a bit by the * addition of remove_mapping(). If success is returned, the caller may * attempt to reuse this page for another destination. */ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { struct page *page = buf->page; struct address_space *mapping = page_mapping(page); lock_page(page); WARN_ON(!PageUptodate(page)); /* * At least for ext2 with nobh option, we need to wait on writeback * completing on this page, since we'll remove it from the pagecache. * Otherwise truncate wont wait on the page, allowing the disk * blocks to be reused by someone else before we actually wrote our * data to them. fs corruption ensues. */ wait_on_page_writeback(page); if (PagePrivate(page)) try_to_release_page(page, mapping_gfp_mask(mapping)); if (!remove_mapping(mapping, page)) { unlock_page(page); return 1; } buf->flags |= PIPE_BUF_FLAG_LRU; return 0; }
/* * This is for invalidate_mapping_pages(). That function can be called at * any time, and is not supposed to throw away dirty pages. But pages can * be marked dirty at any time too, so use remove_mapping which safely * discards clean, unused pages. * * Returns non-zero if the page was successfully invalidated. */ static int invalidate_complete_page(struct address_space *mapping, struct page *page) { int ret; if (page->mapping != mapping) return 0; if (page_has_private(page) && !try_to_release_page(page, 0)) return 0; ret = remove_mapping(mapping, page); return ret; }
int main(int argc, char **argv) { struct paging_state *s = (struct paging_state *) malloc(sizeof(struct paging_state)); // Create Pointer to Pointer to the Root Node. s->phys_to_virt = (struct avl_node **) malloc(sizeof(struct avl_node *)); s->virt_to_phys = (struct avl_node **) malloc(sizeof(struct avl_node *)); int verbose = atoi(argv[1]); int no = atoi(argv[2]); long cop[no]; long x; for(int i = 0; i < no; i++){ scanf("%lu", &x); cop[i] = x; insert_mapping(s, x, x); if(verbose){ printf("inserted %lu\n", x); //struct avl_node *root = *(s->phys_to_virt); //printf("Pointer to Tree Root: %p\n", s->phys_to_virt); //printf("Pointer to Root Node: %p\n", *(s->phys_to_virt)); //printf("Current Root Node Value: %lu\n", (root->mapping->paddr)); } } for(int i = 0; i < no; i++){ addr_t res = avl_lookup(s, cop[i]); // printf("looking up %lu\n", cop[i]); if(verbose) printf("Found %lu (%i/%i)\n", res, i, no); } if (verbose) printf("FOUND TRACE COMPLETE\n"); for (int i = 0; i < no; i++) { if (verbose) printf("Removing %lu\n", cop[i]); remove_mapping(s, cop[i], cop[i]); if (verbose) printf("Removed %lu\n", cop[i]); } if (verbose) printf("Testing Complete\n"); //clean_tree(*(s->virt_to_phys), false); //clean_tree(*(s->phys_to_virt), true); }
/* * Attempt to steal a page from a pipe buffer. This should perhaps go into * a vm helper function, it's already simplified quite a bit by the * addition of remove_mapping(). If success is returned, the caller may * attempt to reuse this page for another destination. */ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { struct page *page = buf->page; struct address_space *mapping; lock_page(page); mapping = page_mapping(page); if (mapping) { WARN_ON(!PageUptodate(page)); /* * At least for ext2 with nobh option, we need to wait on * writeback completing on this page, since we'll remove it * from the pagecache. Otherwise truncate wont wait on the * page, allowing the disk blocks to be reused by someone else * before we actually wrote our data to them. fs corruption * ensues. */ wait_on_page_writeback(page); if (PagePrivate(page) && try_to_release_page(page, GFP_KERNEL)) goto out_unlock; /* * If we succeeded in removing the mapping, set LRU flag * and return good. */ if (remove_mapping(mapping, page)) { buf->flags |= PIPE_BUF_FLAG_LRU; return 0; } } /* * Raced with truncate or failed to remove page from current * address space, unlock and return failure. */ out_unlock: unlock_page(page); return 1; }
struct sysret sys_monitor_nullify_cap(capaddr_t cptr, uint8_t bits) { struct capability *root = &dcb_current->cspace.cap; struct cte *cte; errval_t err = caps_lookup_slot(root, cptr, bits, &cte, CAPRIGHTS_READ_WRITE); if (err_is_fail(err)) { return SYSRET(err); } // remove from MDB remove_mapping(cte); // zero-out cap entry assert(!mdb_reachable(cte)); memset(cte, 0, sizeof(*cte)); return SYSRET(SYS_ERR_OK); }
/* * This is the core of the direct rendering engine. */ struct page * sgi_graphics_nopage (struct vm_area_struct *vma, unsigned long address, int no_share) { pgd_t *pgd; pmd_t *pmd; pte_t *pte; int board = GRAPHICS_CARD (vma->vm_dentry->d_inode->i_rdev); unsigned long virt_add, phys_add; #ifdef DEBUG printk ("Got a page fault for board %d address=%lx guser=%lx\n", board, address, (unsigned long) cards[board].g_user); #endif /* Figure out if another process has this mapped, and revoke the mapping * in that case. */ if (cards[board].g_user && cards[board].g_user != current) { /* FIXME: save graphics context here, dump it to rendering * node? */ remove_mapping(cards[board].g_user, vma->vm_start, vma->vm_end); } cards [board].g_user = current; /* Map the physical address of the newport registers into the address * space of this process */ virt_add = address & PAGE_MASK; phys_add = cards[board].g_regs + virt_add - vma->vm_start; remap_page_range(virt_add, phys_add, PAGE_SIZE, vma->vm_page_prot); pgd = pgd_offset(current->mm, address); pmd = pmd_offset(pgd, address); pte = pte_offset(pmd, address); return pte_page(*pte); }
void evict(){ /* struct list_elem* e= first_clean(); */ /* printf("thread %d ,waiting for flock",thread_current()->tid); */ lock_acquire(&framelock); struct list_elem* e= list_front(&framelist); struct frame *f = list_entry(e, struct frame , elem); bool lock_held=lock_held_by_current_thread(&f->thread->SPT_lock); /* printf("framelock acquired %d %d current:%d \n",f->thread->tid,lock_held,thread_current()->tid); */ ASSERT(!lock_held) lock_acquire(&f->thread->SPT_lock); /* printf("Evict called by %d ,evicted thread,%d evicted address %p and lock_held=%d and after acquire=%d\n",thread_current()->tid,f->thread->tid,f->upage,lock_held,lock_held_by_current_thread(&f->thread->SPT_lock)); */ if (pagedir_is_dirty(f->thread->pagedir,f->upage)) /* if(e==NULL) */ { ASSERT(f!=NULL); /* printf("sector %d \n",sector); */ struct page_data *p = SPT_lookup(f->upage,f->thread); if(p!=NULL){ if(p->loc==mmap1) { printf("removing2\n"); write_back_map(f->upage,p->file,p->offset); remove_mapping(f->upage,f->kpage,e,f->thread); lock_release(&framelock); if(!lock_held)lock_release(&f->thread->SPT_lock); return; } else { ASSERT(p->loc!=swap); SPT_remove(p->vaddr,f->thread); } } int sector= write_page_to_swap(f->kpage); /* printf("evicton 4 \n"); */ struct page_data *p1= malloc(sizeof(struct page_data)); p1->loc= swap; p1->vaddr=f->upage; p1->block_sector=sector; SPT_insert(p1,f->thread); /* printf("evicton 5 \n"); */ /* printf("in evic3 %p , %p thread: %d\n", f->upage,f->kpage,f->thread->tid); */ remove_mapping(f->upage,f->kpage,e,f->thread); } else { /* printf("found a non dirty page \n"); */ remove_mapping(f->upage,f->kpage,e,f->thread); } /* printf("evict end%d and lock held =%d,lock_held2=%d \n",thread_current()->tid,lock_held_by_current_thread(&f->thread->SPT_lock),lock_held); */ lock_release(&f->thread->SPT_lock); lock_release(&framelock); /* PANIC("OUT OF MEMORY"); */ }