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