Changes in kernel/generic/src/mm/frame.c [af96dd57:05411e8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/frame.c
raf96dd57 r05411e8 66 66 * available. 67 67 */ 68 staticmutex_t mem_avail_mtx;69 staticcondvar_t mem_avail_cv;70 s tatic size_t mem_avail_req = 0; /**< Number of frames requested. */71 s tatic size_t mem_avail_gen = 0; /**< Generation counter. */68 mutex_t mem_avail_mtx; 69 condvar_t mem_avail_cv; 70 size_t mem_avail_req = 0; /**< Number of frames requested. */ 71 size_t mem_avail_gen = 0; /**< Generation counter. */ 72 72 73 73 /********************/ … … 75 75 /********************/ 76 76 77 NO_TRACEstatic inline size_t frame_index(zone_t *zone, frame_t *frame)77 static inline size_t frame_index(zone_t *zone, frame_t *frame) 78 78 { 79 79 return (size_t) (frame - zone->frames); 80 80 } 81 81 82 NO_TRACEstatic inline size_t frame_index_abs(zone_t *zone, frame_t *frame)82 static inline size_t frame_index_abs(zone_t *zone, frame_t *frame) 83 83 { 84 84 return (size_t) (frame - zone->frames) + zone->base; 85 85 } 86 86 87 NO_TRACEstatic inline bool frame_index_valid(zone_t *zone, size_t index)87 static inline bool frame_index_valid(zone_t *zone, size_t index) 88 88 { 89 89 return (index < zone->count); 90 90 } 91 91 92 NO_TRACEstatic inline size_t make_frame_index(zone_t *zone, frame_t *frame)92 static inline size_t make_frame_index(zone_t *zone, frame_t *frame) 93 93 { 94 94 return (frame - zone->frames); … … 100 100 * 101 101 */ 102 NO_TRACEstatic void frame_initialize(frame_t *frame)102 static void frame_initialize(frame_t *frame) 103 103 { 104 104 frame->refcount = 1; … … 121 121 * 122 122 */ 123 NO_TRACE static size_t zones_insert_zone(pfn_t base, size_t count, 124 zone_flags_t flags) 123 static size_t zones_insert_zone(pfn_t base, size_t count) 125 124 { 126 125 if (zones.count + 1 == ZONES_MAX) { … … 132 131 for (i = 0; i < zones.count; i++) { 133 132 /* Check for overlap */ 134 if (overlaps(zones.info[i].base, zones.info[i].count, 135 base, count)) { 136 137 /* 138 * If the overlaping zones are of the same type 139 * and the new zone is completely within the previous 140 * one, then quietly ignore the new zone. 141 * 142 */ 143 144 if ((zones.info[i].flags != flags) || 145 (!iswithin(zones.info[i].base, zones.info[i].count, 146 base, count))) { 147 printf("Zone (%p, %p) overlaps with previous zone (%p, %p)!\n", 148 PFN2ADDR(base), PFN2ADDR(count), 149 PFN2ADDR(zones.info[i].base), 150 PFN2ADDR(zones.info[i].count)); 151 } 152 133 if (overlaps(base, count, 134 zones.info[i].base, zones.info[i].count)) { 135 printf("Zones overlap!\n"); 153 136 return (size_t) -1; 154 137 } … … 161 144 for (j = zones.count; j > i; j--) { 162 145 zones.info[j] = zones.info[j - 1]; 163 if (zones.info[j].buddy_system != NULL) 164 zones.info[j].buddy_system->data = 165 (void *) &zones.info[j]; 146 zones.info[j].buddy_system->data = 147 (void *) &zones.info[j - 1]; 166 148 } 167 149 … … 180 162 */ 181 163 #ifdef CONFIG_DEBUG 182 NO_TRACEstatic size_t total_frames_free(void)164 static size_t total_frames_free(void) 183 165 { 184 166 size_t total = 0; … … 189 171 return total; 190 172 } 191 #endif /* CONFIG_DEBUG */173 #endif 192 174 193 175 /** Find a zone with a given frames. … … 203 185 * 204 186 */ 205 NO_TRACEsize_t find_zone(pfn_t frame, size_t count, size_t hint)187 size_t find_zone(pfn_t frame, size_t count, size_t hint) 206 188 { 207 189 if (hint >= zones.count) … … 217 199 if (i >= zones.count) 218 200 i = 0; 219 220 201 } while (i != hint); 221 202 … … 224 205 225 206 /** @return True if zone can allocate specified order */ 226 NO_TRACEstatic bool zone_can_alloc(zone_t *zone, uint8_t order)207 static bool zone_can_alloc(zone_t *zone, uint8_t order) 227 208 { 228 209 return (zone_flags_available(zone->flags) … … 240 221 * 241 222 */ 242 NO_TRACE static size_t find_free_zone(uint8_t order, zone_flags_t flags, 243 size_t hint) 223 static size_t find_free_zone(uint8_t order, zone_flags_t flags, size_t hint) 244 224 { 245 225 if (hint >= zones.count) … … 262 242 if (i >= zones.count) 263 243 i = 0; 264 265 244 } while (i != hint); 266 245 … … 281 260 * 282 261 */ 283 NO_TRACE static link_t *zone_buddy_find_block(buddy_system_t *buddy,284 link_t *child,uint8_t order)262 static link_t *zone_buddy_find_block(buddy_system_t *buddy, link_t *child, 263 uint8_t order) 285 264 { 286 265 frame_t *frame = list_get_instance(child, frame_t, buddy_link); … … 304 283 * 305 284 */ 306 NO_TRACE static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, 307 link_t *block) 285 static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, link_t *block) 308 286 { 309 287 frame_t *frame = list_get_instance(block, frame_t, buddy_link); … … 318 296 index = (frame_index(zone, frame)) + 319 297 (1 << frame->buddy_order); 320 } else { 298 } else { /* is_right */ 321 299 index = (frame_index(zone, frame)) - 322 300 (1 << frame->buddy_order); … … 341 319 * 342 320 */ 343 NO_TRACEstatic link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)321 static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block) 344 322 { 345 323 frame_t *frame_l = list_get_instance(block, frame_t, buddy_link); … … 359 337 * 360 338 */ 361 NO_TRACE static link_t *zone_buddy_coalesce(buddy_system_t *buddy,362 link_t *block_ 1, link_t *block_2)339 static link_t *zone_buddy_coalesce(buddy_system_t *buddy, link_t *block_1, 340 link_t *block_2) 363 341 { 364 342 frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link); … … 375 353 * 376 354 */ 377 NO_TRACEstatic void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,355 static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block, 378 356 uint8_t order) 379 357 { … … 389 367 * 390 368 */ 391 NO_TRACE static uint8_t zone_buddy_get_order(buddy_system_t *buddy, 392 link_t *block) 369 static uint8_t zone_buddy_get_order(buddy_system_t *buddy, link_t *block) 393 370 { 394 371 return list_get_instance(block, frame_t, buddy_link)->buddy_order; … … 401 378 * 402 379 */ 403 NO_TRACE static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t *block)380 static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t * block) 404 381 { 405 382 list_get_instance(block, frame_t, buddy_link)->refcount = 1; … … 410 387 * @param buddy Buddy system. 411 388 * @param block Buddy system block. 412 * 413 */ 414 NO_TRACE static void zone_buddy_mark_available(buddy_system_t *buddy, 415 link_t *block) 389 */ 390 static void zone_buddy_mark_available(buddy_system_t *buddy, link_t *block) 416 391 { 417 392 list_get_instance(block, frame_t, buddy_link)->refcount = 0; … … 444 419 * 445 420 */ 446 NO_TRACEstatic pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)421 static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order) 447 422 { 448 423 ASSERT(zone_flags_available(zone->flags)); … … 472 447 * 473 448 */ 474 NO_TRACEstatic void zone_frame_free(zone_t *zone, size_t frame_idx)449 static void zone_frame_free(zone_t *zone, size_t frame_idx) 475 450 { 476 451 ASSERT(zone_flags_available(zone->flags)); … … 493 468 494 469 /** Return frame from zone. */ 495 NO_TRACEstatic frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)470 static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx) 496 471 { 497 472 ASSERT(frame_idx < zone->count); … … 500 475 501 476 /** Mark frame in zone unavailable to allocation. */ 502 NO_TRACEstatic void zone_mark_unavailable(zone_t *zone, size_t frame_idx)477 static void zone_mark_unavailable(zone_t *zone, size_t frame_idx) 503 478 { 504 479 ASSERT(zone_flags_available(zone->flags)); … … 529 504 * 530 505 */ 531 NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, 532 buddy_system_t *buddy) 506 static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, buddy_system_t *buddy) 533 507 { 534 508 ASSERT(zone_flags_available(zones.info[z1].flags)); … … 626 600 * 627 601 */ 628 NO_TRACEstatic void return_config_frames(size_t znum, pfn_t pfn, size_t count)602 static void return_config_frames(size_t znum, pfn_t pfn, size_t count) 629 603 { 630 604 ASSERT(zone_flags_available(zones.info[znum].flags)); … … 661 635 * 662 636 */ 663 NO_TRACE static void zone_reduce_region(size_t znum, pfn_t frame_idx, 664 size_t count) 637 static void zone_reduce_region(size_t znum, pfn_t frame_idx, size_t count) 665 638 { 666 639 ASSERT(zone_flags_available(zones.info[znum].flags)); … … 700 673 bool zone_merge(size_t z1, size_t z2) 701 674 { 702 irq_spinlock_lock(&zones.lock, true); 675 ipl_t ipl = interrupts_disable(); 676 spinlock_lock(&zones.lock); 703 677 704 678 bool ret = true; … … 763 737 for (i = z2 + 1; i < zones.count; i++) { 764 738 zones.info[i - 1] = zones.info[i]; 765 if (zones.info[i - 1].buddy_system != NULL) 766 zones.info[i - 1].buddy_system->data = 767 (void *) &zones.info[i - 1]; 739 zones.info[i - 1].buddy_system->data = 740 (void *) &zones.info[i - 1]; 768 741 } 769 742 … … 771 744 772 745 errout: 773 irq_spinlock_unlock(&zones.lock, true); 746 spinlock_unlock(&zones.lock); 747 interrupts_restore(ipl); 774 748 775 749 return ret; … … 803 777 * 804 778 */ 805 NO_TRACE static void zone_construct(zone_t *zone, buddy_system_t *buddy, 806 pfn_t start, size_t count, zone_flags_t flags) 779 static void zone_construct(zone_t *zone, buddy_system_t *buddy, pfn_t start, size_t count, zone_flags_t flags) 807 780 { 808 781 zone->base = start; … … 847 820 * 848 821 */ 849 size_t zone_conf_size(size_t count)822 uintptr_t zone_conf_size(size_t count) 850 823 { 851 824 return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count))); … … 868 841 * 869 842 */ 870 size_t zone_create(pfn_t start, size_t count, pfn_t confframe, 871 zone_flags_t flags) 872 { 873 irq_spinlock_lock(&zones.lock, true);843 size_t zone_create(pfn_t start, size_t count, pfn_t confframe, zone_flags_t flags) 844 { 845 ipl_t ipl = interrupts_disable(); 846 spinlock_lock(&zones.lock); 874 847 875 848 if (zone_flags_available(flags)) { /* Create available zone */ … … 914 887 } 915 888 916 size_t znum = zones_insert_zone(start, count , flags);889 size_t znum = zones_insert_zone(start, count); 917 890 if (znum == (size_t) -1) { 918 irq_spinlock_unlock(&zones.lock, true); 891 spinlock_unlock(&zones.lock); 892 interrupts_restore(ipl); 919 893 return (size_t) -1; 920 894 } … … 931 905 } 932 906 933 irq_spinlock_unlock(&zones.lock, true); 907 spinlock_unlock(&zones.lock); 908 interrupts_restore(ipl); 934 909 935 910 return znum; … … 937 912 938 913 /* Non-available zone */ 939 size_t znum = zones_insert_zone(start, count , flags);914 size_t znum = zones_insert_zone(start, count); 940 915 if (znum == (size_t) -1) { 941 irq_spinlock_unlock(&zones.lock, true); 916 spinlock_unlock(&zones.lock); 917 interrupts_restore(ipl); 942 918 return (size_t) -1; 943 919 } 944 920 zone_construct(&zones.info[znum], NULL, start, count, flags); 945 921 946 irq_spinlock_unlock(&zones.lock, true); 922 spinlock_unlock(&zones.lock); 923 interrupts_restore(ipl); 947 924 948 925 return znum; … … 956 933 void frame_set_parent(pfn_t pfn, void *data, size_t hint) 957 934 { 958 irq_spinlock_lock(&zones.lock, true); 935 ipl_t ipl = interrupts_disable(); 936 spinlock_lock(&zones.lock); 959 937 960 938 size_t znum = find_zone(pfn, 1, hint); … … 965 943 pfn - zones.info[znum].base)->parent = data; 966 944 967 irq_spinlock_unlock(&zones.lock, true); 945 spinlock_unlock(&zones.lock); 946 interrupts_restore(ipl); 968 947 } 969 948 970 949 void *frame_get_parent(pfn_t pfn, size_t hint) 971 950 { 972 irq_spinlock_lock(&zones.lock, true); 951 ipl_t ipl = interrupts_disable(); 952 spinlock_lock(&zones.lock); 973 953 974 954 size_t znum = find_zone(pfn, 1, hint); … … 979 959 pfn - zones.info[znum].base)->parent; 980 960 981 irq_spinlock_unlock(&zones.lock, true); 961 spinlock_unlock(&zones.lock); 962 interrupts_restore(ipl); 982 963 983 964 return res; … … 996 977 { 997 978 size_t size = ((size_t) 1) << order; 979 ipl_t ipl; 998 980 size_t hint = pzone ? (*pzone) : 0; 999 981 1000 982 loop: 1001 irq_spinlock_lock(&zones.lock, true); 983 ipl = interrupts_disable(); 984 spinlock_lock(&zones.lock); 1002 985 1003 986 /* … … 1010 993 if it does not help, reclaim all */ 1011 994 if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) { 1012 irq_spinlock_unlock(&zones.lock, true); 995 spinlock_unlock(&zones.lock); 996 interrupts_restore(ipl); 997 1013 998 size_t freed = slab_reclaim(0); 1014 irq_spinlock_lock(&zones.lock, true); 999 1000 ipl = interrupts_disable(); 1001 spinlock_lock(&zones.lock); 1015 1002 1016 1003 if (freed > 0) … … 1019 1006 1020 1007 if (znum == (size_t) -1) { 1021 irq_spinlock_unlock(&zones.lock, true); 1008 spinlock_unlock(&zones.lock); 1009 interrupts_restore(ipl); 1010 1022 1011 freed = slab_reclaim(SLAB_RECLAIM_ALL); 1023 irq_spinlock_lock(&zones.lock, true); 1012 1013 ipl = interrupts_disable(); 1014 spinlock_lock(&zones.lock); 1024 1015 1025 1016 if (freed > 0) … … 1031 1022 if (znum == (size_t) -1) { 1032 1023 if (flags & FRAME_ATOMIC) { 1033 irq_spinlock_unlock(&zones.lock, true); 1024 spinlock_unlock(&zones.lock); 1025 interrupts_restore(ipl); 1034 1026 return NULL; 1035 1027 } … … 1039 1031 #endif 1040 1032 1041 irq_spinlock_unlock(&zones.lock, true); 1042 1033 spinlock_unlock(&zones.lock); 1034 interrupts_restore(ipl); 1035 1043 1036 if (!THREAD) 1044 1037 panic("Cannot wait for memory to become available."); … … 1076 1069 + zones.info[znum].base; 1077 1070 1078 irq_spinlock_unlock(&zones.lock, true); 1071 spinlock_unlock(&zones.lock); 1072 interrupts_restore(ipl); 1079 1073 1080 1074 if (pzone) … … 1098 1092 void frame_free(uintptr_t frame) 1099 1093 { 1100 irq_spinlock_lock(&zones.lock, true); 1094 ipl_t ipl = interrupts_disable(); 1095 spinlock_lock(&zones.lock); 1101 1096 1102 1097 /* … … 1110 1105 zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base); 1111 1106 1112 irq_spinlock_unlock(&zones.lock, true); 1107 spinlock_unlock(&zones.lock); 1108 interrupts_restore(ipl); 1113 1109 1114 1110 /* … … 1134 1130 * 1135 1131 */ 1136 NO_TRACE void frame_reference_add(pfn_t pfn) 1137 { 1138 irq_spinlock_lock(&zones.lock, true); 1132 void frame_reference_add(pfn_t pfn) 1133 { 1134 ipl_t ipl = interrupts_disable(); 1135 spinlock_lock(&zones.lock); 1139 1136 1140 1137 /* … … 1147 1144 zones.info[znum].frames[pfn - zones.info[znum].base].refcount++; 1148 1145 1149 irq_spinlock_unlock(&zones.lock, true);1150 } 1151 1152 /** Mark given range unavailable in frame zones. 1153 * 1154 */ 1155 NO_TRACE void frame_mark_unavailable(pfn_t start, size_t count) 1156 { 1157 irq_spinlock_lock(&zones.lock, true);1146 spinlock_unlock(&zones.lock); 1147 interrupts_restore(ipl); 1148 } 1149 1150 /** Mark given range unavailable in frame zones. */ 1151 void frame_mark_unavailable(pfn_t start, size_t count) 1152 { 1153 ipl_t ipl = interrupts_disable(); 1154 spinlock_lock(&zones.lock); 1158 1155 1159 1156 size_t i; … … 1167 1164 } 1168 1165 1169 irq_spinlock_unlock(&zones.lock, true); 1170 } 1171 1172 /** Initialize physical memory management. 1173 * 1174 */ 1166 spinlock_unlock(&zones.lock); 1167 interrupts_restore(ipl); 1168 } 1169 1170 /** Initialize physical memory management. */ 1175 1171 void frame_init(void) 1176 1172 { 1177 1173 if (config.cpu_active == 1) { 1178 1174 zones.count = 0; 1179 irq_spinlock_initialize(&zones.lock, "frame.zones.lock");1175 spinlock_initialize(&zones.lock, "zones.lock"); 1180 1176 mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE); 1181 1177 condvar_initialize(&mem_avail_cv); … … 1208 1204 } 1209 1205 1210 /** Return total size of all zones. 1211 * 1212 */ 1206 /** Return total size of all zones. */ 1213 1207 uint64_t zones_total_size(void) 1214 1208 { 1215 irq_spinlock_lock(&zones.lock, true); 1209 ipl_t ipl = interrupts_disable(); 1210 spinlock_lock(&zones.lock); 1216 1211 1217 1212 uint64_t total = 0; … … 1220 1215 total += (uint64_t) FRAMES2SIZE(zones.info[i].count); 1221 1216 1222 irq_spinlock_unlock(&zones.lock, true); 1217 spinlock_unlock(&zones.lock); 1218 interrupts_restore(ipl); 1223 1219 1224 1220 return total; … … 1233 1229 ASSERT(free != NULL); 1234 1230 1235 irq_spinlock_lock(&zones.lock, true); 1231 ipl_t ipl = interrupts_disable(); 1232 spinlock_lock(&zones.lock); 1236 1233 1237 1234 *total = 0; … … 1251 1248 } 1252 1249 1253 irq_spinlock_unlock(&zones.lock, true); 1254 } 1255 1256 /** Prints list of zones. 1257 * 1258 */ 1250 spinlock_unlock(&zones.lock); 1251 interrupts_restore(ipl); 1252 } 1253 1254 /** Prints list of zones. */ 1259 1255 void zones_print_list(void) 1260 1256 { 1261 1257 #ifdef __32_BITS__ 1262 printf("[nr] [base addr] [frames ] [flags ] [free frames ] [busy frames ]\n"); 1258 printf("# base address frames flags free frames busy frames\n"); 1259 printf("-- ------------ ------------ -------- ------------ ------------\n"); 1263 1260 #endif 1264 1261 1265 1262 #ifdef __64_BITS__ 1266 printf("[nr] [base address ] [frames ] [flags ] [free frames ] [busy frames ]\n"); 1263 printf("# base address frames flags free frames busy frames\n"); 1264 printf("-- -------------------- ------------ -------- ------------ ------------\n"); 1267 1265 #endif 1268 1266 … … 1280 1278 size_t i; 1281 1279 for (i = 0;; i++) { 1282 irq_spinlock_lock(&zones.lock, true); 1280 ipl_t ipl = interrupts_disable(); 1281 spinlock_lock(&zones.lock); 1283 1282 1284 1283 if (i >= zones.count) { 1285 irq_spinlock_unlock(&zones.lock, true); 1284 spinlock_unlock(&zones.lock); 1285 interrupts_restore(ipl); 1286 1286 break; 1287 1287 } … … 1293 1293 size_t busy_count = zones.info[i].busy_count; 1294 1294 1295 irq_spinlock_unlock(&zones.lock, true); 1295 spinlock_unlock(&zones.lock); 1296 interrupts_restore(ipl); 1296 1297 1297 1298 bool available = zone_flags_available(flags); 1298 1299 1299 printf("%- 4" PRIs, i);1300 printf("%-2" PRIs, i); 1300 1301 1301 1302 #ifdef __32_BITS__ 1302 printf(" %10p", base);1303 printf(" %10p", base); 1303 1304 #endif 1304 1305 1305 1306 #ifdef __64_BITS__ 1306 printf(" %18p", base);1307 printf(" %18p", base); 1307 1308 #endif 1308 1309 … … 1313 1314 1314 1315 if (available) 1315 printf("%1 4" PRIs " %14" PRIs,1316 printf("%12" PRIs " %12" PRIs, 1316 1317 free_count, busy_count); 1317 1318 … … 1327 1328 void zone_print_one(size_t num) 1328 1329 { 1329 irq_spinlock_lock(&zones.lock, true); 1330 ipl_t ipl = interrupts_disable(); 1331 spinlock_lock(&zones.lock); 1330 1332 size_t znum = (size_t) -1; 1331 1333 … … 1339 1341 1340 1342 if (znum == (size_t) -1) { 1341 irq_spinlock_unlock(&zones.lock, true); 1343 spinlock_unlock(&zones.lock); 1344 interrupts_restore(ipl); 1342 1345 printf("Zone not found.\n"); 1343 1346 return; … … 1350 1353 size_t busy_count = zones.info[i].busy_count; 1351 1354 1352 irq_spinlock_unlock(&zones.lock, true); 1355 spinlock_unlock(&zones.lock); 1356 interrupts_restore(ipl); 1353 1357 1354 1358 bool available = zone_flags_available(flags);
Note:
See TracChangeset
for help on using the changeset viewer.