Changeset a9e8b39 in mainline
- Timestamp:
- 2006-04-26T17:56:23Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ed6c81f1
- Parents:
- 6fa476f7
- Location:
- generic
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/include/mm/as.h
r6fa476f7 ra9e8b39 60 60 #define AS_AREA_DEVICE 8 61 61 62 /** Address space area attributes. */ 63 #define AS_AREA_ATTR_NONE 0 64 #define AS_AREA_ATTR_PARTIAL 1 /* Not fully initialized area. */ 65 62 66 /** Address space area structure. 63 67 * … … 67 71 struct as_area { 68 72 SPINLOCK_DECLARE(lock); 69 int flags; 73 int flags; /**< Flags related to the memory represented by the address space area. */ 74 int attributes; /**< Attributes related to the address space area itself. */ 70 75 count_t pages; /**< Size of this area in multiples of PAGE_SIZE. */ 71 76 __address base; /**< Base address of this area. */ … … 113 118 extern void as_init(void); 114 119 extern as_t *as_create(int flags); 115 extern as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base );120 extern as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base, int attrs); 116 121 extern __address as_area_resize(as_t *as, __address address, size_t size, int flags); 117 int as_area_send(task_id_t id, __address base);122 int as_area_send(task_id_t dst_id, __address base); 118 123 extern void as_set_mapping(as_t *as, __address page, __address frame); 119 124 extern int as_page_fault(__address page); -
generic/src/ddi/ddi.c
r6fa476f7 ra9e8b39 93 93 if (writable) 94 94 flags |= AS_AREA_WRITE; 95 if (!as_area_create(t->as, flags, pages * PAGE_SIZE, vp )) {95 if (!as_area_create(t->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE)) { 96 96 /* 97 97 * The address space area could not have been created. -
generic/src/lib/elf.c
r6fa476f7 ra9e8b39 187 187 segment = ((void *) elf) + entry->p_offset; 188 188 189 a = as_area_create(as, flags, entry->p_memsz, entry->p_vaddr );189 a = as_area_create(as, flags, entry->p_memsz, entry->p_vaddr, AS_AREA_ATTR_NONE); 190 190 if (!a) 191 191 return EE_MEMORY; -
generic/src/mm/as.c
r6fa476f7 ra9e8b39 127 127 * 128 128 * @param as Target address space. 129 * @param flags Flags of the area .129 * @param flags Flags of the area memory. 130 130 * @param size Size of area. 131 131 * @param base Base address of area. 132 * @param attrs Attributes of the area. 132 133 * 133 134 * @return Address space area on success or NULL on failure. 134 135 */ 135 as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base )136 as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base, int attrs) 136 137 { 137 138 ipl_t ipl; … … 162 163 163 164 a->flags = flags; 165 a->attributes = attrs; 164 166 a->pages = SIZE2FRAMES(size); 165 167 a->base = base; … … 290 292 * space area and any associated mapping is preserved. 291 293 * 292 * @param id Task ID of the accepting task.293 * @param base Base address of the source address space area.294 * @param dst_id Task ID of the accepting task. 295 * @param src_base Base address of the source address space area. 294 296 * 295 297 * @return 0 on success or ENOENT if there is no such task or … … 299 301 * address space area. 300 302 */ 301 int as_area_send(task_id_t id, __addressbase)303 int as_area_send(task_id_t dst_id, __address src_base) 302 304 { 303 305 ipl_t ipl; 304 306 task_t *t; 305 307 count_t i; 306 as_t * as;308 as_t *dst_as; 307 309 __address dst_base; 308 int flags;309 size_t s ize;310 as_area_t * area;310 int src_flags; 311 size_t src_size; 312 as_area_t *src_area, *dst_area; 311 313 312 314 ipl = interrupts_disable(); 313 315 spinlock_lock(&tasks_lock); 314 316 315 t = task_find_by_id( id);317 t = task_find_by_id(dst_id); 316 318 if (!NULL) { 317 319 spinlock_unlock(&tasks_lock); … … 323 325 spinlock_unlock(&tasks_lock); 324 326 325 as = t->as;327 dst_as = t->as; 326 328 dst_base = (__address) t->accept_arg.base; 327 329 328 if ( as == AS) {330 if (dst_as == AS) { 329 331 /* 330 332 * The two tasks share the entire address space. … … 337 339 338 340 spinlock_lock(&AS->lock); 339 area = find_area_and_lock(AS,base);340 if (! area) {341 src_area = find_area_and_lock(AS, src_base); 342 if (!src_area) { 341 343 /* 342 344 * Could not find the source address space area. … … 347 349 return ENOENT; 348 350 } 349 s ize =area->pages * PAGE_SIZE;350 flags =area->flags;351 spinlock_unlock(& area->lock);351 src_size = src_area->pages * PAGE_SIZE; 352 src_flags = src_area->flags; 353 spinlock_unlock(&src_area->lock); 352 354 spinlock_unlock(&AS->lock); 353 355 354 if ((t->accept_arg.task_id != TASK->taskid) || (t->accept_arg.size != s ize) ||355 (t->accept_arg.flags != flags)) {356 if ((t->accept_arg.task_id != TASK->taskid) || (t->accept_arg.size != src_size) || 357 (t->accept_arg.flags != src_flags)) { 356 358 /* 357 359 * Discrepancy in either task ID, size or flags. … … 363 365 364 366 /* 365 * Create copy of the address space area. 366 */ 367 if (!as_area_create(as, flags, size, dst_base)) { 367 * Create copy of the source address space area. 368 * The destination area is created with AS_AREA_ATTR_PARTIAL 369 * attribute set which prevents race condition with 370 * preliminary as_page_fault() calls. 371 */ 372 dst_area = as_area_create(dst_as, src_flags, src_size, dst_base, AS_AREA_ATTR_PARTIAL); 373 if (!dst_area) { 368 374 /* 369 375 * Destination address space area could not be created. … … 374 380 } 375 381 376 /*377 * NOTE: we have just introduced a race condition.378 * The destination task can try to attempt the newly379 * created area before its mapping is copied from380 * the source address space area. In result, frames381 * can get lost.382 *383 * Currently, this race is not solved, but one of the384 * possible solutions would be to sleep in as_page_fault()385 * when this situation is detected.386 */387 388 382 memsetb((__address) &t->accept_arg, sizeof(as_area_acptsnd_arg_t), 0); 389 383 spinlock_unlock(&t->lock); … … 392 386 * Avoid deadlock by first locking the address space with lower address. 393 387 */ 394 if ( as < AS) {395 spinlock_lock(& as->lock);388 if (dst_as < AS) { 389 spinlock_lock(&dst_as->lock); 396 390 spinlock_lock(&AS->lock); 397 391 } else { 398 392 spinlock_lock(&AS->lock); 399 spinlock_lock(& as->lock);400 } 401 402 for (i = 0; i < SIZE2FRAMES(s ize); i++) {393 spinlock_lock(&dst_as->lock); 394 } 395 396 for (i = 0; i < SIZE2FRAMES(src_size); i++) { 403 397 pte_t *pte; 404 398 __address frame; 405 399 406 400 page_table_lock(AS, false); 407 pte = page_mapping_find(AS, base + i*PAGE_SIZE);401 pte = page_mapping_find(AS, src_base + i*PAGE_SIZE); 408 402 if (pte && PTE_VALID(pte)) { 409 403 ASSERT(PTE_PRESENT(pte)); 410 404 frame = PTE_GET_FRAME(pte); 411 if (!( flags & AS_AREA_DEVICE))405 if (!(src_flags & AS_AREA_DEVICE)) 412 406 frame_reference_add(ADDR2PFN(frame)); 413 407 page_table_unlock(AS, false); … … 417 411 } 418 412 419 page_table_lock(as, false); 420 page_mapping_insert(as, dst_base + i*PAGE_SIZE, frame, area_flags_to_page_flags(flags)); 421 page_table_unlock(as, false); 422 } 413 page_table_lock(dst_as, false); 414 page_mapping_insert(dst_as, dst_base + i*PAGE_SIZE, frame, area_flags_to_page_flags(src_flags)); 415 page_table_unlock(dst_as, false); 416 } 417 418 /* 419 * Now the destination address space area has been 420 * fully initialized. Clear the AS_AREA_ATTR_PARTIAL 421 * attribute. 422 */ 423 spinlock_lock(&dst_area->lock); 424 dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL; 425 spinlock_unlock(&dst_area->lock); 423 426 424 427 spinlock_unlock(&AS->lock); 425 spinlock_unlock(& as->lock);428 spinlock_unlock(&dst_as->lock); 426 429 interrupts_restore(ipl); 427 430 … … 485 488 spinlock_unlock(&AS->lock); 486 489 return 0; 490 } 491 492 if (area->attributes & AS_AREA_ATTR_PARTIAL) { 493 /* 494 * The address space area is not fully initialized. 495 * Avoid possible race by returning error. 496 */ 497 spinlock_unlock(&area->lock); 498 spinlock_unlock(&AS->lock); 499 return 0; 487 500 } 488 501 … … 840 853 __native sys_as_area_create(__address address, size_t size, int flags) 841 854 { 842 if (as_area_create(AS, flags, size, address ))855 if (as_area_create(AS, flags, size, address, AS_AREA_ATTR_NONE)) 843 856 return (__native) address; 844 857 else -
generic/src/proc/task.c
r6fa476f7 ra9e8b39 152 152 * Create the data as_area. 153 153 */ 154 a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE, LOADED_PROG_STACK_PAGES_NO*PAGE_SIZE, USTACK_ADDRESS); 154 a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE, LOADED_PROG_STACK_PAGES_NO*PAGE_SIZE, 155 USTACK_ADDRESS, AS_AREA_ATTR_NONE); 155 156 156 157 t = thread_create(uinit, kernel_uarg, task, 0, "uinit");
Note:
See TracChangeset
for help on using the changeset viewer.