Changes in kernel/generic/src/mm/frame.c [e2650d3:98000fb] in mainline
- File:
-
- 1 edited
-
kernel/generic/src/mm/frame.c (modified) (59 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/frame.c
re2650d3 r98000fb 43 43 */ 44 44 45 #include < typedefs.h>45 #include <arch/types.h> 46 46 #include <mm/frame.h> 47 47 #include <mm/as.h> … … 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 } … … 179 162 */ 180 163 #ifdef CONFIG_DEBUG 181 NO_TRACEstatic size_t total_frames_free(void)164 static size_t total_frames_free(void) 182 165 { 183 166 size_t total = 0; … … 188 171 return total; 189 172 } 190 #endif /* CONFIG_DEBUG */173 #endif 191 174 192 175 /** Find a zone with a given frames. … … 202 185 * 203 186 */ 204 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) 205 188 { 206 189 if (hint >= zones.count) … … 216 199 if (i >= zones.count) 217 200 i = 0; 218 219 201 } while (i != hint); 220 202 … … 223 205 224 206 /** @return True if zone can allocate specified order */ 225 NO_TRACEstatic bool zone_can_alloc(zone_t *zone, uint8_t order)207 static bool zone_can_alloc(zone_t *zone, uint8_t order) 226 208 { 227 209 return (zone_flags_available(zone->flags) … … 239 221 * 240 222 */ 241 NO_TRACE static size_t find_free_zone(uint8_t order, zone_flags_t flags, 242 size_t hint) 223 static size_t find_free_zone(uint8_t order, zone_flags_t flags, size_t hint) 243 224 { 244 225 if (hint >= zones.count) … … 261 242 if (i >= zones.count) 262 243 i = 0; 263 264 244 } while (i != hint); 265 245 … … 280 260 * 281 261 */ 282 NO_TRACE static link_t *zone_buddy_find_block(buddy_system_t *buddy,283 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) 284 264 { 285 265 frame_t *frame = list_get_instance(child, frame_t, buddy_link); … … 303 283 * 304 284 */ 305 NO_TRACE static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, 306 link_t *block) 285 static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, link_t *block) 307 286 { 308 287 frame_t *frame = list_get_instance(block, frame_t, buddy_link); … … 317 296 index = (frame_index(zone, frame)) + 318 297 (1 << frame->buddy_order); 319 } else { /* is_right */298 } else { /* is_right */ 320 299 index = (frame_index(zone, frame)) - 321 300 (1 << frame->buddy_order); … … 340 319 * 341 320 */ 342 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) 343 322 { 344 323 frame_t *frame_l = list_get_instance(block, frame_t, buddy_link); … … 358 337 * 359 338 */ 360 NO_TRACE static link_t *zone_buddy_coalesce(buddy_system_t *buddy,361 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) 362 341 { 363 342 frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link); … … 374 353 * 375 354 */ 376 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, 377 356 uint8_t order) 378 357 { … … 388 367 * 389 368 */ 390 NO_TRACE static uint8_t zone_buddy_get_order(buddy_system_t *buddy, 391 link_t *block) 369 static uint8_t zone_buddy_get_order(buddy_system_t *buddy, link_t *block) 392 370 { 393 371 return list_get_instance(block, frame_t, buddy_link)->buddy_order; … … 400 378 * 401 379 */ 402 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) 403 381 { 404 382 list_get_instance(block, frame_t, buddy_link)->refcount = 1; … … 409 387 * @param buddy Buddy system. 410 388 * @param block Buddy system block. 411 * 412 */ 413 NO_TRACE static void zone_buddy_mark_available(buddy_system_t *buddy, 414 link_t *block) 389 */ 390 static void zone_buddy_mark_available(buddy_system_t *buddy, link_t *block) 415 391 { 416 392 list_get_instance(block, frame_t, buddy_link)->refcount = 0; … … 443 419 * 444 420 */ 445 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) 446 422 { 447 423 ASSERT(zone_flags_available(zone->flags)); … … 471 447 * 472 448 */ 473 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) 474 450 { 475 451 ASSERT(zone_flags_available(zone->flags)); … … 492 468 493 469 /** Return frame from zone. */ 494 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) 495 471 { 496 472 ASSERT(frame_idx < zone->count); … … 499 475 500 476 /** Mark frame in zone unavailable to allocation. */ 501 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) 502 478 { 503 479 ASSERT(zone_flags_available(zone->flags)); … … 528 504 * 529 505 */ 530 NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, 531 buddy_system_t *buddy) 506 static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, buddy_system_t *buddy) 532 507 { 533 508 ASSERT(zone_flags_available(zones.info[z1].flags)); … … 625 600 * 626 601 */ 627 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) 628 603 { 629 604 ASSERT(zone_flags_available(zones.info[znum].flags)); … … 660 635 * 661 636 */ 662 NO_TRACE static void zone_reduce_region(size_t znum, pfn_t frame_idx, 663 size_t count) 637 static void zone_reduce_region(size_t znum, pfn_t frame_idx, size_t count) 664 638 { 665 639 ASSERT(zone_flags_available(zones.info[znum].flags)); … … 699 673 bool zone_merge(size_t z1, size_t z2) 700 674 { 701 irq_spinlock_lock(&zones.lock, true); 675 ipl_t ipl = interrupts_disable(); 676 spinlock_lock(&zones.lock); 702 677 703 678 bool ret = true; … … 769 744 770 745 errout: 771 irq_spinlock_unlock(&zones.lock, true); 746 spinlock_unlock(&zones.lock); 747 interrupts_restore(ipl); 772 748 773 749 return ret; … … 801 777 * 802 778 */ 803 NO_TRACE static void zone_construct(zone_t *zone, buddy_system_t *buddy, 804 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) 805 780 { 806 781 zone->base = start; … … 845 820 * 846 821 */ 847 size_t zone_conf_size(size_t count)822 uintptr_t zone_conf_size(size_t count) 848 823 { 849 824 return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count))); … … 866 841 * 867 842 */ 868 size_t zone_create(pfn_t start, size_t count, pfn_t confframe, 869 zone_flags_t flags) 870 { 871 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); 872 847 873 848 if (zone_flags_available(flags)) { /* Create available zone */ … … 912 887 } 913 888 914 size_t znum = zones_insert_zone(start, count , flags);889 size_t znum = zones_insert_zone(start, count); 915 890 if (znum == (size_t) -1) { 916 irq_spinlock_unlock(&zones.lock, true); 891 spinlock_unlock(&zones.lock); 892 interrupts_restore(ipl); 917 893 return (size_t) -1; 918 894 } … … 929 905 } 930 906 931 irq_spinlock_unlock(&zones.lock, true); 907 spinlock_unlock(&zones.lock); 908 interrupts_restore(ipl); 932 909 933 910 return znum; … … 935 912 936 913 /* Non-available zone */ 937 size_t znum = zones_insert_zone(start, count , flags);914 size_t znum = zones_insert_zone(start, count); 938 915 if (znum == (size_t) -1) { 939 irq_spinlock_unlock(&zones.lock, true); 916 spinlock_unlock(&zones.lock); 917 interrupts_restore(ipl); 940 918 return (size_t) -1; 941 919 } 942 920 zone_construct(&zones.info[znum], NULL, start, count, flags); 943 921 944 irq_spinlock_unlock(&zones.lock, true); 922 spinlock_unlock(&zones.lock); 923 interrupts_restore(ipl); 945 924 946 925 return znum; … … 954 933 void frame_set_parent(pfn_t pfn, void *data, size_t hint) 955 934 { 956 irq_spinlock_lock(&zones.lock, true); 935 ipl_t ipl = interrupts_disable(); 936 spinlock_lock(&zones.lock); 957 937 958 938 size_t znum = find_zone(pfn, 1, hint); … … 963 943 pfn - zones.info[znum].base)->parent = data; 964 944 965 irq_spinlock_unlock(&zones.lock, true); 945 spinlock_unlock(&zones.lock); 946 interrupts_restore(ipl); 966 947 } 967 948 968 949 void *frame_get_parent(pfn_t pfn, size_t hint) 969 950 { 970 irq_spinlock_lock(&zones.lock, true); 951 ipl_t ipl = interrupts_disable(); 952 spinlock_lock(&zones.lock); 971 953 972 954 size_t znum = find_zone(pfn, 1, hint); … … 977 959 pfn - zones.info[znum].base)->parent; 978 960 979 irq_spinlock_unlock(&zones.lock, true); 961 spinlock_unlock(&zones.lock); 962 interrupts_restore(ipl); 980 963 981 964 return res; … … 994 977 { 995 978 size_t size = ((size_t) 1) << order; 979 ipl_t ipl; 996 980 size_t hint = pzone ? (*pzone) : 0; 997 981 998 982 loop: 999 irq_spinlock_lock(&zones.lock, true); 983 ipl = interrupts_disable(); 984 spinlock_lock(&zones.lock); 1000 985 1001 986 /* … … 1008 993 if it does not help, reclaim all */ 1009 994 if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) { 1010 irq_spinlock_unlock(&zones.lock, true); 995 spinlock_unlock(&zones.lock); 996 interrupts_restore(ipl); 997 1011 998 size_t freed = slab_reclaim(0); 1012 irq_spinlock_lock(&zones.lock, true); 999 1000 ipl = interrupts_disable(); 1001 spinlock_lock(&zones.lock); 1013 1002 1014 1003 if (freed > 0) … … 1017 1006 1018 1007 if (znum == (size_t) -1) { 1019 irq_spinlock_unlock(&zones.lock, true); 1008 spinlock_unlock(&zones.lock); 1009 interrupts_restore(ipl); 1010 1020 1011 freed = slab_reclaim(SLAB_RECLAIM_ALL); 1021 irq_spinlock_lock(&zones.lock, true); 1012 1013 ipl = interrupts_disable(); 1014 spinlock_lock(&zones.lock); 1022 1015 1023 1016 if (freed > 0) … … 1029 1022 if (znum == (size_t) -1) { 1030 1023 if (flags & FRAME_ATOMIC) { 1031 irq_spinlock_unlock(&zones.lock, true); 1024 spinlock_unlock(&zones.lock); 1025 interrupts_restore(ipl); 1032 1026 return NULL; 1033 1027 } … … 1037 1031 #endif 1038 1032 1039 irq_spinlock_unlock(&zones.lock, true); 1040 1041 if (!THREAD) 1042 panic("Cannot wait for memory to become available."); 1033 spinlock_unlock(&zones.lock); 1034 interrupts_restore(ipl); 1043 1035 1044 1036 /* … … 1074 1066 + zones.info[znum].base; 1075 1067 1076 irq_spinlock_unlock(&zones.lock, true); 1068 spinlock_unlock(&zones.lock); 1069 interrupts_restore(ipl); 1077 1070 1078 1071 if (pzone) … … 1096 1089 void frame_free(uintptr_t frame) 1097 1090 { 1098 irq_spinlock_lock(&zones.lock, true); 1091 ipl_t ipl = interrupts_disable(); 1092 spinlock_lock(&zones.lock); 1099 1093 1100 1094 /* … … 1108 1102 zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base); 1109 1103 1110 irq_spinlock_unlock(&zones.lock, true); 1104 spinlock_unlock(&zones.lock); 1105 interrupts_restore(ipl); 1111 1106 1112 1107 /* … … 1132 1127 * 1133 1128 */ 1134 NO_TRACE void frame_reference_add(pfn_t pfn) 1135 { 1136 irq_spinlock_lock(&zones.lock, true); 1129 void frame_reference_add(pfn_t pfn) 1130 { 1131 ipl_t ipl = interrupts_disable(); 1132 spinlock_lock(&zones.lock); 1137 1133 1138 1134 /* … … 1145 1141 zones.info[znum].frames[pfn - zones.info[znum].base].refcount++; 1146 1142 1147 irq_spinlock_unlock(&zones.lock, true);1148 } 1149 1150 /** Mark given range unavailable in frame zones. 1151 * 1152 */ 1153 NO_TRACE void frame_mark_unavailable(pfn_t start, size_t count) 1154 { 1155 irq_spinlock_lock(&zones.lock, true);1143 spinlock_unlock(&zones.lock); 1144 interrupts_restore(ipl); 1145 } 1146 1147 /** Mark given range unavailable in frame zones. */ 1148 void frame_mark_unavailable(pfn_t start, size_t count) 1149 { 1150 ipl_t ipl = interrupts_disable(); 1151 spinlock_lock(&zones.lock); 1156 1152 1157 1153 size_t i; … … 1165 1161 } 1166 1162 1167 irq_spinlock_unlock(&zones.lock, true); 1168 } 1169 1170 /** Initialize physical memory management. 1171 * 1172 */ 1163 spinlock_unlock(&zones.lock); 1164 interrupts_restore(ipl); 1165 } 1166 1167 /** Initialize physical memory management. */ 1173 1168 void frame_init(void) 1174 1169 { 1175 1170 if (config.cpu_active == 1) { 1176 1171 zones.count = 0; 1177 irq_spinlock_initialize(&zones.lock, "frame.zones.lock");1172 spinlock_initialize(&zones.lock, "zones.lock"); 1178 1173 mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE); 1179 1174 condvar_initialize(&mem_avail_cv); … … 1206 1201 } 1207 1202 1208 /** Return total size of all zones. 1209 * 1210 */ 1211 uint64_t zones_total_size(void) 1212 { 1213 irq_spinlock_lock(&zones.lock, true); 1203 /** Return total size of all zones. */ 1204 uint64_t zone_total_size(void) 1205 { 1206 ipl_t ipl = interrupts_disable(); 1207 spinlock_lock(&zones.lock); 1214 1208 1215 1209 uint64_t total = 0; … … 1218 1212 total += (uint64_t) FRAMES2SIZE(zones.info[i].count); 1219 1213 1220 irq_spinlock_unlock(&zones.lock, true); 1214 spinlock_unlock(&zones.lock); 1215 interrupts_restore(ipl); 1221 1216 1222 1217 return total; 1223 1218 } 1224 1219 1225 void zones_stats(uint64_t *total, uint64_t *unavail, uint64_t *busy, 1226 uint64_t *free) 1227 { 1228 ASSERT(total != NULL); 1229 ASSERT(unavail != NULL); 1230 ASSERT(busy != NULL); 1231 ASSERT(free != NULL); 1232 1233 irq_spinlock_lock(&zones.lock, true); 1234 1235 *total = 0; 1236 *unavail = 0; 1237 *busy = 0; 1238 *free = 0; 1239 1240 size_t i; 1241 for (i = 0; i < zones.count; i++) { 1242 *total += (uint64_t) FRAMES2SIZE(zones.info[i].count); 1243 1244 if (zone_flags_available(zones.info[i].flags)) { 1245 *busy += (uint64_t) FRAMES2SIZE(zones.info[i].busy_count); 1246 *free += (uint64_t) FRAMES2SIZE(zones.info[i].free_count); 1247 } else 1248 *unavail += (uint64_t) FRAMES2SIZE(zones.info[i].count); 1249 } 1250 1251 irq_spinlock_unlock(&zones.lock, true); 1252 } 1253 1254 /** Prints list of zones. 1255 * 1256 */ 1257 void zones_print_list(void) 1220 /** Prints list of zones. */ 1221 void zone_print_list(void) 1258 1222 { 1259 1223 #ifdef __32_BITS__ 1260 printf("[nr] [base addr] [frames ] [flags ] [free frames ] [busy frames ]\n"); 1224 printf("# base address frames flags free frames busy frames\n"); 1225 printf("-- ------------ ------------ -------- ------------ ------------\n"); 1261 1226 #endif 1262 1227 1263 1228 #ifdef __64_BITS__ 1264 printf("[nr] [base address ] [frames ] [flags ] [free frames ] [busy frames ]\n"); 1229 printf("# base address frames flags free frames busy frames\n"); 1230 printf("-- -------------------- ------------ -------- ------------ ------------\n"); 1265 1231 #endif 1266 1232 … … 1278 1244 size_t i; 1279 1245 for (i = 0;; i++) { 1280 irq_spinlock_lock(&zones.lock, true); 1246 ipl_t ipl = interrupts_disable(); 1247 spinlock_lock(&zones.lock); 1281 1248 1282 1249 if (i >= zones.count) { 1283 irq_spinlock_unlock(&zones.lock, true); 1250 spinlock_unlock(&zones.lock); 1251 interrupts_restore(ipl); 1284 1252 break; 1285 1253 } … … 1291 1259 size_t busy_count = zones.info[i].busy_count; 1292 1260 1293 irq_spinlock_unlock(&zones.lock, true); 1261 spinlock_unlock(&zones.lock); 1262 interrupts_restore(ipl); 1294 1263 1295 1264 bool available = zone_flags_available(flags); 1296 1265 1297 printf("%- 4" PRIs, i);1266 printf("%-2" PRIs, i); 1298 1267 1299 1268 #ifdef __32_BITS__ 1300 printf(" %10p", base);1269 printf(" %10p", base); 1301 1270 #endif 1302 1271 1303 1272 #ifdef __64_BITS__ 1304 printf(" %18p", base);1273 printf(" %18p", base); 1305 1274 #endif 1306 1275 … … 1311 1280 1312 1281 if (available) 1313 printf("%1 4" PRIs " %14" PRIs,1282 printf("%12" PRIs " %12" PRIs, 1314 1283 free_count, busy_count); 1315 1284 … … 1325 1294 void zone_print_one(size_t num) 1326 1295 { 1327 irq_spinlock_lock(&zones.lock, true); 1296 ipl_t ipl = interrupts_disable(); 1297 spinlock_lock(&zones.lock); 1328 1298 size_t znum = (size_t) -1; 1329 1299 … … 1337 1307 1338 1308 if (znum == (size_t) -1) { 1339 irq_spinlock_unlock(&zones.lock, true); 1309 spinlock_unlock(&zones.lock); 1310 interrupts_restore(ipl); 1340 1311 printf("Zone not found.\n"); 1341 1312 return; … … 1348 1319 size_t busy_count = zones.info[i].busy_count; 1349 1320 1350 irq_spinlock_unlock(&zones.lock, true); 1321 spinlock_unlock(&zones.lock); 1322 interrupts_restore(ipl); 1351 1323 1352 1324 bool available = zone_flags_available(flags);
Note:
See TracChangeset
for help on using the changeset viewer.
