Changeset cefb126 in mainline for kernel/generic/src/mm/as.c


Ignore:
Timestamp:
2010-07-02T14:19:30Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
89c57b6
Parents:
fe7abd0 (diff), e3ee9b9 (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.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/as.c

    rfe7abd0 rcefb126  
    116116as_t *AS_KERNEL = NULL;
    117117
    118 static unsigned int area_flags_to_page_flags(unsigned int);
    119 static as_area_t *find_area_and_lock(as_t *, uintptr_t);
    120 static bool check_area_conflicts(as_t *, uintptr_t, size_t, as_area_t *);
    121 static void sh_info_remove_reference(share_info_t *);
    122 
    123118static int as_constructor(void *obj, unsigned int flags)
    124119{
     
    239234       
    240235        spinlock_unlock(&asidlock);
     236        interrupts_restore(ipl);
     237
    241238       
    242239        /*
     
    266263#endif
    267264       
    268         interrupts_restore(ipl);
    269        
    270265        slab_free(as_slab, as);
    271266}
     
    296291        if (atomic_predec(&as->refcount) == 0)
    297292                as_destroy(as);
     293}
     294
     295/** Check area conflicts with other areas.
     296 *
     297 * @param as         Address space.
     298 * @param va         Starting virtual address of the area being tested.
     299 * @param size       Size of the area being tested.
     300 * @param avoid_area Do not touch this area.
     301 *
     302 * @return True if there is no conflict, false otherwise.
     303 *
     304 */
     305static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
     306    as_area_t *avoid_area)
     307{
     308        ASSERT(mutex_locked(&as->lock));
     309       
     310        /*
     311         * We don't want any area to have conflicts with NULL page.
     312         *
     313         */
     314        if (overlaps(va, size, NULL, PAGE_SIZE))
     315                return false;
     316       
     317        /*
     318         * The leaf node is found in O(log n), where n is proportional to
     319         * the number of address space areas belonging to as.
     320         * The check for conflicts is then attempted on the rightmost
     321         * record in the left neighbour, the leftmost record in the right
     322         * neighbour and all records in the leaf node itself.
     323         *
     324         */
     325        btree_node_t *leaf;
     326        as_area_t *area =
     327            (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     328        if (area) {
     329                if (area != avoid_area)
     330                        return false;
     331        }
     332       
     333        /* First, check the two border cases. */
     334        btree_node_t *node =
     335            btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
     336        if (node) {
     337                area = (as_area_t *) node->value[node->keys - 1];
     338               
     339                mutex_lock(&area->lock);
     340               
     341                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     342                        mutex_unlock(&area->lock);
     343                        return false;
     344                }
     345               
     346                mutex_unlock(&area->lock);
     347        }
     348       
     349        node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
     350        if (node) {
     351                area = (as_area_t *) node->value[0];
     352               
     353                mutex_lock(&area->lock);
     354               
     355                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     356                        mutex_unlock(&area->lock);
     357                        return false;
     358                }
     359               
     360                mutex_unlock(&area->lock);
     361        }
     362       
     363        /* Second, check the leaf node. */
     364        btree_key_t i;
     365        for (i = 0; i < leaf->keys; i++) {
     366                area = (as_area_t *) leaf->value[i];
     367               
     368                if (area == avoid_area)
     369                        continue;
     370               
     371                mutex_lock(&area->lock);
     372               
     373                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     374                        mutex_unlock(&area->lock);
     375                        return false;
     376                }
     377               
     378                mutex_unlock(&area->lock);
     379        }
     380       
     381        /*
     382         * So far, the area does not conflict with other areas.
     383         * Check if it doesn't conflict with kernel address space.
     384         *
     385         */
     386        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
     387                return !overlaps(va, size,
     388                    KERNEL_ADDRESS_SPACE_START,
     389                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
     390        }
     391       
     392        return true;
    298393}
    299394
     
    327422                return NULL;
    328423       
    329         ipl_t ipl = interrupts_disable();
    330424        mutex_lock(&as->lock);
    331425       
    332426        if (!check_area_conflicts(as, base, size, NULL)) {
    333427                mutex_unlock(&as->lock);
    334                 interrupts_restore(ipl);
    335428                return NULL;
    336429        }
     
    357450       
    358451        mutex_unlock(&as->lock);
    359         interrupts_restore(ipl);
    360452       
    361453        return area;
     454}
     455
     456/** Find address space area and lock it.
     457 *
     458 * @param as Address space.
     459 * @param va Virtual address.
     460 *
     461 * @return Locked address space area containing va on success or
     462 *         NULL on failure.
     463 *
     464 */
     465static as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
     466{
     467        ASSERT(mutex_locked(&as->lock));
     468       
     469        btree_node_t *leaf;
     470        as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     471        if (area) {
     472                /* va is the base address of an address space area */
     473                mutex_lock(&area->lock);
     474                return area;
     475        }
     476       
     477        /*
     478         * Search the leaf node and the righmost record of its left neighbour
     479         * to find out whether this is a miss or va belongs to an address
     480         * space area found there.
     481         *
     482         */
     483       
     484        /* First, search the leaf node itself. */
     485        btree_key_t i;
     486       
     487        for (i = 0; i < leaf->keys; i++) {
     488                area = (as_area_t *) leaf->value[i];
     489               
     490                mutex_lock(&area->lock);
     491               
     492                if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
     493                        return area;
     494               
     495                mutex_unlock(&area->lock);
     496        }
     497       
     498        /*
     499         * Second, locate the left neighbour and test its last record.
     500         * Because of its position in the B+tree, it must have base < va.
     501         *
     502         */
     503        btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
     504        if (lnode) {
     505                area = (as_area_t *) lnode->value[lnode->keys - 1];
     506               
     507                mutex_lock(&area->lock);
     508               
     509                if (va < area->base + area->pages * PAGE_SIZE)
     510                        return area;
     511               
     512                mutex_unlock(&area->lock);
     513        }
     514       
     515        return NULL;
    362516}
    363517
     
    376530int as_area_resize(as_t *as, uintptr_t address, size_t size, unsigned int flags)
    377531{
    378         ipl_t ipl = interrupts_disable();
    379532        mutex_lock(&as->lock);
    380533       
     
    386539        if (!area) {
    387540                mutex_unlock(&as->lock);
    388                 interrupts_restore(ipl);
    389541                return ENOENT;
    390542        }
     
    398550                mutex_unlock(&area->lock);
    399551                mutex_unlock(&as->lock);
    400                 interrupts_restore(ipl);
    401552                return ENOTSUP;
    402553        }
     
    410561                mutex_unlock(&area->lock);
    411562                mutex_unlock(&as->lock);
    412                 interrupts_restore(ipl);
    413563                return ENOTSUP;
    414564        }
     
    422572                mutex_unlock(&area->lock);
    423573                mutex_unlock(&as->lock);
    424                 interrupts_restore(ipl);
    425574                return EPERM;
    426575        }
     
    441590                 *
    442591                 */
    443                 tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base +
    444                     pages * PAGE_SIZE, area->pages - pages);
     592                ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
     593                    area->base + pages * PAGE_SIZE, area->pages - pages);
    445594               
    446595                /*
     
    536685                as_invalidate_translation_cache(as, area->base +
    537686                    pages * PAGE_SIZE, area->pages - pages);
    538                 tlb_shootdown_finalize();
     687                tlb_shootdown_finalize(ipl);
    539688               
    540689                page_table_unlock(as, false);
     
    549698                        mutex_unlock(&area->lock);
    550699                        mutex_unlock(&as->lock);
    551                         interrupts_restore(ipl);
    552700                        return EADDRNOTAVAIL;
    553701                }
     
    558706        mutex_unlock(&area->lock);
    559707        mutex_unlock(&as->lock);
    560         interrupts_restore(ipl);
    561708       
    562709        return 0;
     710}
     711
     712/** Remove reference to address space area share info.
     713 *
     714 * If the reference count drops to 0, the sh_info is deallocated.
     715 *
     716 * @param sh_info Pointer to address space area share info.
     717 *
     718 */
     719static void sh_info_remove_reference(share_info_t *sh_info)
     720{
     721        bool dealloc = false;
     722       
     723        mutex_lock(&sh_info->lock);
     724        ASSERT(sh_info->refcount);
     725       
     726        if (--sh_info->refcount == 0) {
     727                dealloc = true;
     728                link_t *cur;
     729               
     730                /*
     731                 * Now walk carefully the pagemap B+tree and free/remove
     732                 * reference from all frames found there.
     733                 */
     734                for (cur = sh_info->pagemap.leaf_head.next;
     735                    cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
     736                        btree_node_t *node
     737                            = list_get_instance(cur, btree_node_t, leaf_link);
     738                        btree_key_t i;
     739                       
     740                        for (i = 0; i < node->keys; i++)
     741                                frame_free((uintptr_t) node->value[i]);
     742                }
     743               
     744        }
     745        mutex_unlock(&sh_info->lock);
     746       
     747        if (dealloc) {
     748                btree_destroy(&sh_info->pagemap);
     749                free(sh_info);
     750        }
    563751}
    564752
     
    573761int as_area_destroy(as_t *as, uintptr_t address)
    574762{
    575         ipl_t ipl = interrupts_disable();
    576763        mutex_lock(&as->lock);
    577764       
     
    579766        if (!area) {
    580767                mutex_unlock(&as->lock);
    581                 interrupts_restore(ipl);
    582768                return ENOENT;
    583769        }
     
    590776         * Start TLB shootdown sequence.
    591777         */
    592         tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
     778        ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
     779            area->pages);
    593780       
    594781        /*
     
    637824         */
    638825        as_invalidate_translation_cache(as, area->base, area->pages);
    639         tlb_shootdown_finalize();
     826        tlb_shootdown_finalize(ipl);
    640827       
    641828        page_table_unlock(as, false);
     
    659846       
    660847        mutex_unlock(&as->lock);
    661         interrupts_restore(ipl);
    662848        return 0;
    663849}
     
    690876    as_t *dst_as, uintptr_t dst_base, unsigned int dst_flags_mask)
    691877{
    692         ipl_t ipl = interrupts_disable();
    693878        mutex_lock(&src_as->lock);
    694879        as_area_t *src_area = find_area_and_lock(src_as, src_base);
     
    699884                 */
    700885                mutex_unlock(&src_as->lock);
    701                 interrupts_restore(ipl);
    702886                return ENOENT;
    703887        }
     
    711895                mutex_unlock(&src_area->lock);
    712896                mutex_unlock(&src_as->lock);
    713                 interrupts_restore(ipl);
    714897                return ENOTSUP;
    715898        }
     
    728911                mutex_unlock(&src_area->lock);
    729912                mutex_unlock(&src_as->lock);
    730                 interrupts_restore(ipl);
    731913                return EPERM;
    732914        }
     
    777959                sh_info_remove_reference(sh_info);
    778960               
    779                 interrupts_restore(ipl);
    780961                return ENOMEM;
    781962        }
     
    794975        mutex_unlock(&dst_as->lock);
    795976       
    796         interrupts_restore(ipl);
    797        
    798977        return 0;
    799978}
     
    816995        };
    817996
    818         ASSERT(interrupts_disabled());
    819997        ASSERT(mutex_locked(&area->lock));
    820998       
     
    8231001       
    8241002        return true;
     1003}
     1004
     1005/** Convert address space area flags to page flags.
     1006 *
     1007 * @param aflags Flags of some address space area.
     1008 *
     1009 * @return Flags to be passed to page_mapping_insert().
     1010 *
     1011 */
     1012static unsigned int area_flags_to_page_flags(unsigned int aflags)
     1013{
     1014        unsigned int flags = PAGE_USER | PAGE_PRESENT;
     1015       
     1016        if (aflags & AS_AREA_READ)
     1017                flags |= PAGE_READ;
     1018               
     1019        if (aflags & AS_AREA_WRITE)
     1020                flags |= PAGE_WRITE;
     1021       
     1022        if (aflags & AS_AREA_EXEC)
     1023                flags |= PAGE_EXEC;
     1024       
     1025        if (aflags & AS_AREA_CACHEABLE)
     1026                flags |= PAGE_CACHEABLE;
     1027       
     1028        return flags;
    8251029}
    8261030
     
    8441048        unsigned int page_flags = area_flags_to_page_flags(flags);
    8451049       
    846         ipl_t ipl = interrupts_disable();
    8471050        mutex_lock(&as->lock);
    8481051       
     
    8501053        if (!area) {
    8511054                mutex_unlock(&as->lock);
    852                 interrupts_restore(ipl);
    8531055                return ENOENT;
    8541056        }
     
    8591061                mutex_unlock(&area->lock);
    8601062                mutex_unlock(&as->lock);
    861                 interrupts_restore(ipl);
    8621063                return ENOTSUP;
    8631064        }
     
    8891090         *
    8901091         */
    891         tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
     1092        ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
     1093            area->pages);
    8921094       
    8931095        /*
     
    9361138         */
    9371139        as_invalidate_translation_cache(as, area->base, area->pages);
    938         tlb_shootdown_finalize();
     1140        tlb_shootdown_finalize(ipl);
    9391141       
    9401142        page_table_unlock(as, false);
     
    9781180        mutex_unlock(&area->lock);
    9791181        mutex_unlock(&as->lock);
    980         interrupts_restore(ipl);
    9811182       
    9821183        return 0;
     
    11841385}
    11851386
    1186 /** Convert address space area flags to page flags.
    1187  *
    1188  * @param aflags Flags of some address space area.
    1189  *
    1190  * @return Flags to be passed to page_mapping_insert().
    1191  *
    1192  */
    1193 unsigned int area_flags_to_page_flags(unsigned int aflags)
    1194 {
    1195         unsigned int flags = PAGE_USER | PAGE_PRESENT;
    1196        
    1197         if (aflags & AS_AREA_READ)
    1198                 flags |= PAGE_READ;
    1199                
    1200         if (aflags & AS_AREA_WRITE)
    1201                 flags |= PAGE_WRITE;
    1202        
    1203         if (aflags & AS_AREA_EXEC)
    1204                 flags |= PAGE_EXEC;
    1205        
    1206         if (aflags & AS_AREA_CACHEABLE)
    1207                 flags |= PAGE_CACHEABLE;
    1208        
    1209         return flags;
    1210 }
     1387
    12111388
    12121389/** Compute flags for virtual address translation subsytem.
     
    12191396unsigned int as_area_get_flags(as_area_t *area)
    12201397{
    1221         ASSERT(interrupts_disabled());
    12221398        ASSERT(mutex_locked(&area->lock));
    12231399
     
    12961472/** Test whether page tables are locked.
    12971473 *
    1298  * @param as            Address space where the page tables belong.
    1299  *
    1300  * @return              True if the page tables belonging to the address soace
    1301  *                      are locked, otherwise false.
     1474 * @param as Address space where the page tables belong.
     1475 *
     1476 * @return True if the page tables belonging to the address soace
     1477 *         are locked, otherwise false.
    13021478 */
    13031479bool page_table_locked(as_t *as)
     
    13091485}
    13101486
    1311 
    1312 /** Find address space area and lock it.
    1313  *
    1314  * @param as Address space.
    1315  * @param va Virtual address.
    1316  *
    1317  * @return Locked address space area containing va on success or
    1318  *         NULL on failure.
    1319  *
    1320  */
    1321 as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
    1322 {
    1323         ASSERT(interrupts_disabled());
    1324         ASSERT(mutex_locked(&as->lock));
    1325 
    1326         btree_node_t *leaf;
    1327         as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
    1328         if (area) {
    1329                 /* va is the base address of an address space area */
    1330                 mutex_lock(&area->lock);
    1331                 return area;
    1332         }
    1333        
    1334         /*
    1335          * Search the leaf node and the righmost record of its left neighbour
    1336          * to find out whether this is a miss or va belongs to an address
    1337          * space area found there.
    1338          *
    1339          */
    1340        
    1341         /* First, search the leaf node itself. */
    1342         btree_key_t i;
    1343        
    1344         for (i = 0; i < leaf->keys; i++) {
    1345                 area = (as_area_t *) leaf->value[i];
    1346                
    1347                 mutex_lock(&area->lock);
    1348                
    1349                 if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
    1350                         return area;
    1351                
    1352                 mutex_unlock(&area->lock);
    1353         }
    1354        
    1355         /*
    1356          * Second, locate the left neighbour and test its last record.
    1357          * Because of its position in the B+tree, it must have base < va.
    1358          *
    1359          */
    1360         btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
    1361         if (lnode) {
    1362                 area = (as_area_t *) lnode->value[lnode->keys - 1];
    1363                
    1364                 mutex_lock(&area->lock);
    1365                
    1366                 if (va < area->base + area->pages * PAGE_SIZE)
    1367                         return area;
    1368                
    1369                 mutex_unlock(&area->lock);
    1370         }
    1371        
    1372         return NULL;
    1373 }
    1374 
    1375 /** Check area conflicts with other areas.
    1376  *
    1377  * @param as         Address space.
    1378  * @param va         Starting virtual address of the area being tested.
    1379  * @param size       Size of the area being tested.
    1380  * @param avoid_area Do not touch this area.
    1381  *
    1382  * @return True if there is no conflict, false otherwise.
    1383  *
    1384  */
    1385 bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
    1386     as_area_t *avoid_area)
    1387 {
    1388         ASSERT(interrupts_disabled());
    1389         ASSERT(mutex_locked(&as->lock));
    1390 
    1391         /*
    1392          * We don't want any area to have conflicts with NULL page.
    1393          *
    1394          */
    1395         if (overlaps(va, size, NULL, PAGE_SIZE))
    1396                 return false;
    1397        
    1398         /*
    1399          * The leaf node is found in O(log n), where n is proportional to
    1400          * the number of address space areas belonging to as.
    1401          * The check for conflicts is then attempted on the rightmost
    1402          * record in the left neighbour, the leftmost record in the right
    1403          * neighbour and all records in the leaf node itself.
    1404          *
    1405          */
    1406         btree_node_t *leaf;
    1407         as_area_t *area =
    1408             (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
    1409         if (area) {
    1410                 if (area != avoid_area)
    1411                         return false;
    1412         }
    1413        
    1414         /* First, check the two border cases. */
    1415         btree_node_t *node =
    1416             btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
    1417         if (node) {
    1418                 area = (as_area_t *) node->value[node->keys - 1];
    1419                
    1420                 mutex_lock(&area->lock);
    1421                
    1422                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    1423                         mutex_unlock(&area->lock);
    1424                         return false;
    1425                 }
    1426                
    1427                 mutex_unlock(&area->lock);
    1428         }
    1429        
    1430         node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
    1431         if (node) {
    1432                 area = (as_area_t *) node->value[0];
    1433                
    1434                 mutex_lock(&area->lock);
    1435                
    1436                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    1437                         mutex_unlock(&area->lock);
    1438                         return false;
    1439                 }
    1440                
    1441                 mutex_unlock(&area->lock);
    1442         }
    1443        
    1444         /* Second, check the leaf node. */
    1445         btree_key_t i;
    1446         for (i = 0; i < leaf->keys; i++) {
    1447                 area = (as_area_t *) leaf->value[i];
    1448                
    1449                 if (area == avoid_area)
    1450                         continue;
    1451                
    1452                 mutex_lock(&area->lock);
    1453                
    1454                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    1455                         mutex_unlock(&area->lock);
    1456                         return false;
    1457                 }
    1458                
    1459                 mutex_unlock(&area->lock);
    1460         }
    1461        
    1462         /*
    1463          * So far, the area does not conflict with other areas.
    1464          * Check if it doesn't conflict with kernel address space.
    1465          *
    1466          */
    1467         if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    1468                 return !overlaps(va, size,
    1469                     KERNEL_ADDRESS_SPACE_START,
    1470                     KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
    1471         }
    1472        
    1473         return true;
    1474 }
    1475 
    14761487/** Return size of the address space area with given base.
    14771488 *
     
    14861497        size_t size;
    14871498       
    1488         ipl_t ipl = interrupts_disable();
    14891499        page_table_lock(AS, true);
    14901500        as_area_t *src_area = find_area_and_lock(AS, base);
     
    14971507       
    14981508        page_table_unlock(AS, true);
    1499         interrupts_restore(ipl);
    15001509        return size;
    15011510}
     
    19881997}
    19891998
    1990 /** Remove reference to address space area share info.
    1991  *
    1992  * If the reference count drops to 0, the sh_info is deallocated.
    1993  *
    1994  * @param sh_info Pointer to address space area share info.
    1995  *
    1996  */
    1997 void sh_info_remove_reference(share_info_t *sh_info)
    1998 {
    1999         bool dealloc = false;
    2000        
    2001         mutex_lock(&sh_info->lock);
    2002         ASSERT(sh_info->refcount);
    2003        
    2004         if (--sh_info->refcount == 0) {
    2005                 dealloc = true;
    2006                 link_t *cur;
    2007                
    2008                 /*
    2009                  * Now walk carefully the pagemap B+tree and free/remove
    2010                  * reference from all frames found there.
    2011                  */
    2012                 for (cur = sh_info->pagemap.leaf_head.next;
    2013                     cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
    2014                         btree_node_t *node
    2015                             = list_get_instance(cur, btree_node_t, leaf_link);
    2016                         btree_key_t i;
    2017                        
    2018                         for (i = 0; i < node->keys; i++)
    2019                                 frame_free((uintptr_t) node->value[i]);
    2020                 }
    2021                
    2022         }
    2023         mutex_unlock(&sh_info->lock);
    2024        
    2025         if (dealloc) {
    2026                 btree_destroy(&sh_info->pagemap);
    2027                 free(sh_info);
    2028         }
    2029 }
    2030 
    20311999/*
    20322000 * Address space related syscalls.
     
    20702038void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize)
    20712039{
    2072         ipl_t ipl = interrupts_disable();
    20732040        mutex_lock(&as->lock);
    20742041       
     
    21142081       
    21152082        mutex_unlock(&as->lock);
    2116         interrupts_restore(ipl);
    21172083       
    21182084        *obuf = info;
     
    21272093void as_print(as_t *as)
    21282094{
    2129         ipl_t ipl = interrupts_disable();
    21302095        mutex_lock(&as->lock);
    21312096       
     
    21502115       
    21512116        mutex_unlock(&as->lock);
    2152         interrupts_restore(ipl);
    21532117}
    21542118
Note: See TracChangeset for help on using the changeset viewer.