Changeset 7e4e532 in mainline for genarch/src/mm/asid.c


Ignore:
Timestamp:
2006-02-08T23:37:38Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
874878a
Parents:
bb68433
Message:

Reimplement ASID stealing logic.
This time, hopefully, with correct synchronization.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • genarch/src/mm/asid.c

    rbb68433 r7e4e532  
    4444 * a while.
    4545 *
     46 * This code depends on the fact that ASIDS_ALLOCABLE
     47 * is greater than number of supported CPUs (i.e. the
     48 * amount of concurently active address spaces).
     49 *
    4650 * Architectures that don't have hardware support for address
    4751 * spaces do not compile with this file.
     
    5862
    5963/**
    60  * asidlock protects both the asids_allocated counter
    61  * and the list of address spaces that were already
    62  * assigned ASID.
     64 * asidlock protects the asids_allocated counter.
    6365 */
    6466SPINLOCK_INITIALIZE(asidlock);
     
    6668static count_t asids_allocated = 0;
    6769
    68 /**
    69  * List of address spaces with assigned ASID.
    70  * When the system runs short of allocable
    71  * ASIDS, inactive address spaces are guaranteed
    72  * to be at the beginning of the list.
    73  */
    74 LIST_INITIALIZE(as_with_asid_head);
    75 
    76 
    7770/** Allocate free address space identifier.
    7871 *
    79  * This code depends on the fact that ASIDS_ALLOCABLE
    80  * is greater than number of supported CPUs.
     72 * Interrupts must be disabled and as_lock must be held
     73 * prior to this call
    8174 *
    8275 * @return New ASID.
     
    8477asid_t asid_get(void)
    8578{
    86         ipl_t ipl;
    8779        asid_t asid;
    8880        link_t *tmp;
     
    9385         */
    9486       
    95         ipl = interrupts_disable();
    9687        spinlock_lock(&asidlock);
    9788        if (asids_allocated == ASIDS_ALLOCABLE) {
     
    10798                 * inactive address space.
    10899                 */
    109                 tmp = as_with_asid_head.next;
    110                 ASSERT(tmp != &as_with_asid_head);
     100                ASSERT(!list_empty(&inactive_as_with_asid_head));
     101                tmp = inactive_as_with_asid_head.next;
    111102                list_remove(tmp);
    112103               
    113                 as = list_get_instance(tmp, as_t, as_with_asid_link);
     104                as = list_get_instance(tmp, as_t, inactive_as_with_asid_link);
    114105                spinlock_lock(&as->lock);
    115106
     
    146137       
    147138        spinlock_unlock(&asidlock);
    148         interrupts_restore(ipl);
    149139       
    150140        return asid;
     
    171161        interrupts_restore(ipl);
    172162}
    173 
    174 /** Install ASID.
    175  *
    176  * This function is to be executed on each address space switch.
    177  *
    178  * @param as Address space.
    179  */
    180 void asid_install(as_t *as)
    181 {
    182         ipl_t ipl;
    183        
    184         ipl = interrupts_disable();
    185         spinlock_lock(&asidlock);
    186         spinlock_lock(&as->lock);
    187        
    188         if (as->asid != ASID_KERNEL) {
    189                 if (as->asid != ASID_INVALID) {
    190                         /*
    191                          * This address space has valid ASID.
    192                          * Remove 'as' from the list of address spaces
    193                          * with assigned ASID, so that it can be later
    194                          * appended to the tail of the same list.
    195                          * This is to prevent stealing of ASIDs from
    196                          * recently installed address spaces.
    197                          */
    198                         list_remove(&as->as_with_asid_link);
    199                 } else {
    200                         spinlock_unlock(&as->lock);
    201                         spinlock_unlock(&asidlock);
    202        
    203                         /*
    204                          * This address space doesn't have ASID assigned.
    205                          * It was stolen or the address space is being
    206                          * installed for the first time.
    207                          * Allocate new ASID for it.
    208                          */
    209                         as->asid = asid_get();
    210                         spinlock_lock(&asidlock);
    211                         spinlock_lock(&as->lock);
    212                 }
    213        
    214                 /*
    215                  * Now it is sure that 'as' has ASID.
    216                  * It is therefore appended to the list
    217                  * of address spaces from which it can
    218                  * be stolen.
    219                  */
    220                 list_append(&as->as_with_asid_link, &as_with_asid_head);
    221         }
    222        
    223         spinlock_unlock(&as->lock);
    224         spinlock_unlock(&asidlock);
    225         interrupts_restore(ipl);
    226 }
Note: See TracChangeset for help on using the changeset viewer.