1/*- 2 * Copyright (c) 2002-2005, 2009 Jeffrey Roberson <jeff@FreeBSD.org> 3 * Copyright (c) 2004, 2005 Bosko Milekic <bmilekic@FreeBSD.org> 4 * Copyright (c) 2004-2006 Robert N. M. Watson 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 34 unchanged lines hidden (view full) --- 43 44/* 45 * TODO: 46 * - Improve memory usage for large allocations 47 * - Investigate cache size adjustments 48 */ 49 50#include <sys/cdefs.h> |
51__FBSDID("$FreeBSD: head/sys/vm/uma_core.c 247360 2013-02-26 23:35:27Z attilio $"); |
52 53/* I should really use ktr.. */ 54/* 55#define UMA_DEBUG 1 56#define UMA_DEBUG_ALLOC 1 57#define UMA_DEBUG_ALLOC_1 1 58*/ 59 --- 14 unchanged lines hidden (view full) --- 74#include <sys/proc.h> 75#include <sys/sbuf.h> 76#include <sys/smp.h> 77#include <sys/vmmeter.h> 78 79#include <vm/vm.h> 80#include <vm/vm_object.h> 81#include <vm/vm_page.h> |
82#include <vm/vm_pageout.h> |
83#include <vm/vm_param.h> 84#include <vm/vm_map.h> 85#include <vm/vm_kern.h> 86#include <vm/vm_extern.h> 87#include <vm/uma.h> 88#include <vm/uma_int.h> 89#include <vm/uma_dbg.h> 90 --- 118 unchanged lines hidden (view full) --- 209 */ 210enum zfreeskip { SKIP_NONE, SKIP_DTOR, SKIP_FINI }; 211 212#define ZFREE_STATFAIL 0x00000001 /* Update zone failure statistic. */ 213#define ZFREE_STATFREE 0x00000002 /* Update zone free statistic. */ 214 215/* Prototypes.. */ 216 |
217static void *noobj_alloc(uma_zone_t, int, u_int8_t *, int); |
218static void *page_alloc(uma_zone_t, int, u_int8_t *, int); 219static void *startup_alloc(uma_zone_t, int, u_int8_t *, int); 220static void page_free(void *, int, u_int8_t); 221static uma_slab_t keg_alloc_slab(uma_keg_t, uma_zone_t, int); 222static void cache_drain(uma_zone_t); 223static void bucket_drain(uma_zone_t, uma_bucket_t); 224static void bucket_cache_drain(uma_zone_t zone); 225static int keg_ctor(void *, int, void *, int); --- 800 unchanged lines hidden (view full) --- 1026 * bytes The number of bytes requested 1027 * wait Shall we wait? 1028 * 1029 * Returns: 1030 * A pointer to the alloced memory or possibly 1031 * NULL if M_NOWAIT is set. 1032 */ 1033static void * |
1034noobj_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait) |
1035{ |
1036 TAILQ_HEAD(, vm_page) alloctail; 1037 u_long npages; |
1038 vm_offset_t retkva, zkva; |
1039 vm_page_t p, p_next; |
1040 uma_keg_t keg; 1041 |
1042 TAILQ_INIT(&alloctail); |
1043 keg = zone_first_keg(zone); |
1044 |
1045 npages = howmany(bytes, PAGE_SIZE); 1046 while (npages > 0) { 1047 p = vm_page_alloc(NULL, 0, VM_ALLOC_INTERRUPT | 1048 VM_ALLOC_WIRED | VM_ALLOC_NOOBJ); 1049 if (p != NULL) { 1050 /* 1051 * Since the page does not belong to an object, its 1052 * listq is unused. 1053 */ 1054 TAILQ_INSERT_TAIL(&alloctail, p, listq); 1055 npages--; 1056 continue; |
1057 } |
1058 if (wait & M_WAITOK) { 1059 VM_WAIT; 1060 continue; 1061 } 1062 1063 /* 1064 * Page allocation failed, free intermediate pages and 1065 * exit. 1066 */ 1067 TAILQ_FOREACH_SAFE(p, &alloctail, listq, p_next) { 1068 vm_page_unwire(p, 0); 1069 vm_page_free(p); 1070 } 1071 return (NULL); 1072 } 1073 *flags = UMA_SLAB_PRIV; 1074 zkva = keg->uk_kva + 1075 atomic_fetchadd_long(&keg->uk_offset, round_page(bytes)); 1076 retkva = zkva; 1077 TAILQ_FOREACH(p, &alloctail, listq) { |
1078 pmap_qenter(zkva, &p, 1); |
1079 zkva += PAGE_SIZE; |
1080 } |
1081 1082 return ((void *)retkva); 1083} 1084 1085/* 1086 * Frees a number of pages to the system 1087 * 1088 * Arguments: --- 1922 unchanged lines hidden (view full) --- 3011 keg = zone_first_keg(zone); 3012 keg->uk_flags |= UMA_ZFLAG_PRIVALLOC; 3013 keg->uk_allocf = allocf; 3014 ZONE_UNLOCK(zone); 3015} 3016 3017/* See uma.h */ 3018int |
3019uma_zone_reserve_kva(uma_zone_t zone, int count) |
3020{ 3021 uma_keg_t keg; 3022 vm_offset_t kva; 3023 int pages; 3024 3025 keg = zone_first_keg(zone); 3026 pages = count / keg->uk_ipers; 3027 3028 if (pages * keg->uk_ipers < count) 3029 pages++; 3030 |
3031#ifdef UMA_MD_SMALL_ALLOC 3032 if (keg->uk_ppera > 1) { 3033#else 3034 if (1) { 3035#endif 3036 kva = kmem_alloc_nofault(kernel_map, pages * UMA_SLAB_SIZE); 3037 if (kva == 0) 3038 return (0); 3039 } else 3040 kva = 0; |
3041 ZONE_LOCK(zone); 3042 keg->uk_kva = kva; |
3043 keg->uk_offset = 0; |
3044 keg->uk_maxpages = pages; |
3045#ifdef UMA_MD_SMALL_ALLOC 3046 keg->uk_allocf = (keg->uk_ppera > 1) ? noobj_alloc : uma_small_alloc; 3047#else 3048 keg->uk_allocf = noobj_alloc; 3049#endif |
3050 keg->uk_flags |= UMA_ZONE_NOFREE | UMA_ZFLAG_PRIVALLOC; 3051 ZONE_UNLOCK(zone); 3052 return (1); 3053} 3054 3055/* See uma.h */ 3056void 3057uma_prealloc(uma_zone_t zone, int items) --- 375 unchanged lines hidden --- |