uvm_km_pages
mtx_init(&uvm_km_pages.mtx, IPL_VM);
struct uvm_km_pages uvm_km_pages;
if (!uvm_km_pages.lowat) {
uvm_km_pages.lowat = physmem / 256;
if (uvm_km_pages.lowat < lowat_min)
uvm_km_pages.lowat = lowat_min;
if (uvm_km_pages.lowat > UVM_KM_PAGES_LOWAT_MAX)
uvm_km_pages.lowat = UVM_KM_PAGES_LOWAT_MAX;
uvm_km_pages.hiwat = 4 * uvm_km_pages.lowat;
if (uvm_km_pages.hiwat > UVM_KM_PAGES_HIWAT_MAX)
uvm_km_pages.hiwat = UVM_KM_PAGES_HIWAT_MAX;
bulk = uvm_km_pages.hiwat;
while (len < uvm_km_pages.hiwat && bulk > 0) {
bulk = MIN(bulk, uvm_km_pages.hiwat - len);
uvm_km_pages.page[i] = addr;
uvm_km_pages.free = len;
uvm_km_pages.page[i] = 0;
if (uvm_km_pages.lowat > 512)
uvm_km_pages.lowat = 512;
kthread_create(uvm_km_thread, NULL, &uvm_km_pages.km_proc, "kmthread");
mtx_enter(&uvm_km_pages.mtx);
if (uvm_km_pages.free >= uvm_km_pages.lowat &&
uvm_km_pages.freelist == NULL) {
msleep_nsec(&uvm_km_pages.km_proc, &uvm_km_pages.mtx,
allocmore = uvm_km_pages.free < uvm_km_pages.lowat;
fp = uvm_km_pages.freelist;
uvm_km_pages.freelist = NULL;
uvm_km_pages.freelistlen = 0;
mtx_leave(&uvm_km_pages.mtx);
mtx_enter(&uvm_km_pages.mtx);
if (uvm_km_pages.free ==
nitems(uvm_km_pages.page))
uvm_km_pages.page[uvm_km_pages.free++]
wakeup(&uvm_km_pages.free);
mtx_leave(&uvm_km_pages.mtx);
mtx_enter(&uvm_km_pages.mtx);
if (uvm_km_pages.free < uvm_km_pages.hiwat) {
uvm_km_pages.page[uvm_km_pages.free++] = va;
mtx_leave(&uvm_km_pages.mtx);
mtx_enter(&uvm_km_pages.mtx);
while (uvm_km_pages.free == 0) {
mtx_leave(&uvm_km_pages.mtx);
msleep_nsec(&uvm_km_pages.free, &uvm_km_pages.mtx,
va = uvm_km_pages.page[--uvm_km_pages.free];
if (uvm_km_pages.free < uvm_km_pages.lowat &&
curproc != uvm_km_pages.km_proc) {
wakeup(&uvm_km_pages.km_proc);
mtx_leave(&uvm_km_pages.mtx);
mtx_enter(&uvm_km_pages.mtx);
fp->next = uvm_km_pages.freelist;
uvm_km_pages.freelist = fp;
if (uvm_km_pages.freelistlen++ > 16)
wakeup(&uvm_km_pages.km_proc);
mtx_leave(&uvm_km_pages.mtx);
extern struct uvm_km_pages uvm_km_pages;