diff options
-rw-r--r-- | sys/compat/ndis/kern_ndis.c | 17 | ||||
-rw-r--r-- | sys/compat/ndis/ntoskrnl_var.h | 4 | ||||
-rw-r--r-- | sys/compat/ndis/subr_ntoskrnl.c | 44 |
3 files changed, 47 insertions, 18 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index b6027f5..5694fb3 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -56,8 +56,6 @@ __FBSDID("$FreeBSD$"); #include <sys/bus.h> #include <sys/rman.h> -#include <vm/uma.h> - #include <net/if.h> #include <net/if_arp.h> #include <net/ethernet.h> @@ -120,7 +118,6 @@ static int ndis_enlarge_thrqueue(int); static int ndis_shrink_thrqueue(int); static void ndis_runq(void *); -static uma_zone_t ndis_buffer_zone; struct mtx ndis_thr_mtx; struct mtx ndis_req_mtx; static STAILQ_HEAD(ndisqhead, ndis_req) ndis_ttodo; @@ -160,11 +157,6 @@ ndis_modevent(module_t mod, int cmd, void *arg) patch++; } - /* Initialize TX buffer UMA zone. */ - ndis_buffer_zone = uma_zcreate("NDIS buffer", - sizeof(struct mdl) + (sizeof(vm_offset_t *) * 16), - NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); - ndis_create_kthreads(); TAILQ_INIT(&ndis_devhead); @@ -186,9 +178,6 @@ ndis_modevent(module_t mod, int cmd, void *arg) windrv_unwrap(patch->ipt_wrap); patch++; } - - /* Remove zones */ - uma_zdestroy(ndis_buffer_zone); } break; case MOD_UNLOAD: @@ -208,8 +197,6 @@ ndis_modevent(module_t mod, int cmd, void *arg) patch++; } - /* Remove zones */ - uma_zdestroy(ndis_buffer_zone); break; default: error = EINVAL; @@ -878,7 +865,7 @@ ndis_free_bufs(b0) while(b0 != NULL) { next = b0->mdl_next; - uma_zfree (ndis_buffer_zone, b0); + IoFreeMdl(b0); b0 = next; } @@ -1100,7 +1087,7 @@ ndis_mtop(m0, p) for (m = m0; m != NULL; m = m->m_next) { if (m->m_len == 0) continue; - buf = uma_zalloc(ndis_buffer_zone, M_NOWAIT | M_ZERO); + buf = IoAllocateMdl(m->m_data, m->m_len, FALSE, FALSE, NULL); if (buf == NULL) { ndis_free_packet(*p); *p = NULL; diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h index 0a24471..7a11d53 100644 --- a/sys/compat/ndis/ntoskrnl_var.h +++ b/sys/compat/ndis/ntoskrnl_var.h @@ -100,6 +100,10 @@ typedef struct mdl mdl, ndis_buffer; #define MDL_NETWORK_HEADER 0x1000 #define MDL_MAPPING_CAN_FAIL 0x2000 #define MDL_ALLOCATED_MUST_SUCCEED 0x4000 +#define MDL_ZONE_ALLOCED 0x8000 /* BSD private */ + +#define MDL_ZONE_PAGES 16 +#define MDL_ZONE_SIZE (sizeof(mdl) + (sizeof(vm_offset_t) * MDL_ZONE_PAGES)) /* Note: assumes x86 page size of 4K. */ diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c index 858bd74..bcd1e70 100644 --- a/sys/compat/ndis/subr_ntoskrnl.c +++ b/sys/compat/ndis/subr_ntoskrnl.c @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm.h> #include <vm/vm_param.h> #include <vm/pmap.h> +#include <vm/uma.h> #include <compat/ndis/pe_var.h> #include <compat/ndis/ntoskrnl_var.h> @@ -186,6 +187,7 @@ static kspin_lock ntoskrnl_global; static kspin_lock ntoskrnl_cancellock; static int ntoskrnl_kth = 0; static struct nt_objref_head ntoskrnl_reflist; +static uma_zone_t mdl_zone; int ntoskrnl_libinit() @@ -204,6 +206,22 @@ ntoskrnl_libinit() patch++; } + /* + * MDLs are supposed to be variable size (they describe + * buffers containing some number of pages, but we don't + * know ahead of time how many pages that will be). But + * always allocating them off the heap is very slow. As + * a compromize, we create an MDL UMA zone big enough to + * handle any buffer requiring up to 16 pages, and we + * use those for any MDLs for buffers of 16 pages or less + * in size. For buffers larger than that (which we assume + * will be few and far between, we allocate the MDLs off + * the heap. + */ + + mdl_zone = uma_zcreate("Windows MDL", MDL_ZONE_SIZE, + NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); + return(0); } @@ -219,6 +237,8 @@ ntoskrnl_libfini() patch++; } + uma_zdestroy(mdl_zone); + return(0); } @@ -1726,15 +1746,30 @@ IoAllocateMdl(vaddr, len, secondarybuf, chargequota, iopkt) irp *iopkt; { mdl *m; + int zone = 0; - m = ExAllocatePoolWithTag(NonPagedPool, - MmSizeOfMdl(vaddr, len), 0); + if (MmSizeOfMdl(vaddr, len) > MDL_ZONE_SIZE) + m = ExAllocatePoolWithTag(NonPagedPool, + MmSizeOfMdl(vaddr, len), 0); + else { + m = uma_zalloc(mdl_zone, M_NOWAIT | M_ZERO); + zone++; + } if (m == NULL) return (NULL); MmInitializeMdl(m, vaddr, len); + /* + * MmInitializMdl() clears the flags field, so we + * have to set this here. If the MDL came from the + * MDL UMA zone, tag it so we can release it to + * the right place later. + */ + if (zone) + m->mdl_flags = MDL_ZONE_ALLOCED; + if (iopkt != NULL) { if (secondarybuf == TRUE) { mdl *last; @@ -1759,7 +1794,10 @@ IoFreeMdl(m) if (m == NULL) return; - free (m, M_DEVBUF); + if (m->mdl_flags & MDL_ZONE_ALLOCED) + uma_zfree(mdl_zone, m); + else + ExFreePool(m); return; } |