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