sg_pager.c (9b4fcf851a73554063d4a2de9a4f10cd23a0a4f6) | sg_pager.c (10cf25607484ea85dc2fe22b20e08b824f91a45a) |
---|---|
1/*- 2 * Copyright (c) 2009 Advanced Computing Technologies LLC 3 * Written by: John H. Baldwin <jhb@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 29 unchanged lines hidden (view full) --- 38#include <sys/mutex.h> 39#include <sys/sglist.h> 40#include <vm/vm.h> 41#include <vm/vm_object.h> 42#include <vm/vm_page.h> 43#include <vm/vm_pager.h> 44#include <vm/uma.h> 45 | 1/*- 2 * Copyright (c) 2009 Advanced Computing Technologies LLC 3 * Written by: John H. Baldwin <jhb@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 29 unchanged lines hidden (view full) --- 38#include <sys/mutex.h> 39#include <sys/sglist.h> 40#include <vm/vm.h> 41#include <vm/vm_object.h> 42#include <vm/vm_page.h> 43#include <vm/vm_pager.h> 44#include <vm/uma.h> 45 |
46static void sg_pager_init(void); | |
47static vm_object_t sg_pager_alloc(void *, vm_ooffset_t, vm_prot_t, 48 vm_ooffset_t, struct ucred *); 49static void sg_pager_dealloc(vm_object_t); 50static int sg_pager_getpages(vm_object_t, vm_page_t *, int, int); 51static void sg_pager_putpages(vm_object_t, vm_page_t *, int, 52 boolean_t, int *); 53static boolean_t sg_pager_haspage(vm_object_t, vm_pindex_t, int *, 54 int *); 55 | 46static vm_object_t sg_pager_alloc(void *, vm_ooffset_t, vm_prot_t, 47 vm_ooffset_t, struct ucred *); 48static void sg_pager_dealloc(vm_object_t); 49static int sg_pager_getpages(vm_object_t, vm_page_t *, int, int); 50static void sg_pager_putpages(vm_object_t, vm_page_t *, int, 51 boolean_t, int *); 52static boolean_t sg_pager_haspage(vm_object_t, vm_pindex_t, int *, 53 int *); 54 |
56static uma_zone_t fakepg_zone; 57 58static vm_page_t sg_pager_getfake(vm_paddr_t, vm_memattr_t); 59static void sg_pager_putfake(vm_page_t); 60 | |
61struct pagerops sgpagerops = { | 55struct pagerops sgpagerops = { |
62 .pgo_init = sg_pager_init, | |
63 .pgo_alloc = sg_pager_alloc, 64 .pgo_dealloc = sg_pager_dealloc, 65 .pgo_getpages = sg_pager_getpages, 66 .pgo_putpages = sg_pager_putpages, 67 .pgo_haspage = sg_pager_haspage, 68}; 69 | 56 .pgo_alloc = sg_pager_alloc, 57 .pgo_dealloc = sg_pager_dealloc, 58 .pgo_getpages = sg_pager_getpages, 59 .pgo_putpages = sg_pager_putpages, 60 .pgo_haspage = sg_pager_haspage, 61}; 62 |
70static void 71sg_pager_init(void) 72{ 73 74 fakepg_zone = uma_zcreate("SG fakepg", sizeof(struct vm_page), 75 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 76 UMA_ZONE_NOFREE|UMA_ZONE_VM); 77} 78 | |
79static vm_object_t 80sg_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, 81 vm_ooffset_t foff, struct ucred *cred) 82{ 83 struct sglist *sg; 84 vm_object_t object; 85 vm_pindex_t npages, pindex; 86 int i; --- 46 unchanged lines hidden (view full) --- 133 struct sglist *sg; 134 vm_page_t m; 135 136 /* 137 * Free up our fake pages. 138 */ 139 while ((m = TAILQ_FIRST(&object->un_pager.sgp.sgp_pglist)) != 0) { 140 TAILQ_REMOVE(&object->un_pager.sgp.sgp_pglist, m, pageq); | 63static vm_object_t 64sg_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, 65 vm_ooffset_t foff, struct ucred *cred) 66{ 67 struct sglist *sg; 68 vm_object_t object; 69 vm_pindex_t npages, pindex; 70 int i; --- 46 unchanged lines hidden (view full) --- 117 struct sglist *sg; 118 vm_page_t m; 119 120 /* 121 * Free up our fake pages. 122 */ 123 while ((m = TAILQ_FIRST(&object->un_pager.sgp.sgp_pglist)) != 0) { 124 TAILQ_REMOVE(&object->un_pager.sgp.sgp_pglist, m, pageq); |
141 sg_pager_putfake(m); | 125 vm_page_putfake(m); |
142 } 143 144 sg = object->handle; 145 sglist_free(sg); 146} 147 148static int 149sg_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) --- 38 unchanged lines hidden (view full) --- 188 "WARNING: A device driver has set \"memattr\" inconsistently.\n"); 189 } 190 191 /* Return a fake page for the requested page. */ 192 KASSERT(!(m[reqpage]->flags & PG_FICTITIOUS), 193 ("backing page for SG is fake")); 194 195 /* Construct a new fake page. */ | 126 } 127 128 sg = object->handle; 129 sglist_free(sg); 130} 131 132static int 133sg_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) --- 38 unchanged lines hidden (view full) --- 172 "WARNING: A device driver has set \"memattr\" inconsistently.\n"); 173 } 174 175 /* Return a fake page for the requested page. */ 176 KASSERT(!(m[reqpage]->flags & PG_FICTITIOUS), 177 ("backing page for SG is fake")); 178 179 /* Construct a new fake page. */ |
196 page = sg_pager_getfake(paddr, memattr); | 180 page = vm_page_getfake(paddr, memattr); |
197 VM_OBJECT_LOCK(object); 198 TAILQ_INSERT_TAIL(&object->un_pager.sgp.sgp_pglist, page, pageq); 199 200 /* Free the original pages and insert this fake page into the object. */ 201 for (i = 0; i < count; i++) { 202 vm_page_lock(m[i]); 203 vm_page_free(m[i]); 204 vm_page_unlock(m[i]); --- 19 unchanged lines hidden (view full) --- 224{ 225 226 if (before != NULL) 227 *before = 0; 228 if (after != NULL) 229 *after = 0; 230 return (TRUE); 231} | 181 VM_OBJECT_LOCK(object); 182 TAILQ_INSERT_TAIL(&object->un_pager.sgp.sgp_pglist, page, pageq); 183 184 /* Free the original pages and insert this fake page into the object. */ 185 for (i = 0; i < count; i++) { 186 vm_page_lock(m[i]); 187 vm_page_free(m[i]); 188 vm_page_unlock(m[i]); --- 19 unchanged lines hidden (view full) --- 208{ 209 210 if (before != NULL) 211 *before = 0; 212 if (after != NULL) 213 *after = 0; 214 return (TRUE); 215} |
232 233/* 234 * Create a fictitious page with the specified physical address and memory 235 * attribute. The memory attribute is the only the machine-dependent aspect 236 * of a fictitious page that must be initialized. 237 */ 238static vm_page_t 239sg_pager_getfake(vm_paddr_t paddr, vm_memattr_t memattr) 240{ 241 vm_page_t m; 242 243 m = uma_zalloc(fakepg_zone, M_WAITOK | M_ZERO); 244 m->phys_addr = paddr; 245 m->queue = PQ_NONE; 246 /* Fictitious pages don't use "segind". */ 247 m->flags = PG_FICTITIOUS; 248 /* Fictitious pages don't use "order" or "pool". */ 249 m->oflags = VPO_BUSY; 250 m->wire_count = 1; 251 pmap_page_set_memattr(m, memattr); 252 return (m); 253} 254 255static void 256sg_pager_putfake(vm_page_t m) 257{ 258 259 if (!(m->flags & PG_FICTITIOUS)) 260 panic("sg_pager_putfake: bad page"); 261 uma_zfree(fakepg_zone, m); 262} | |