Changeset 879585a3 in mainline for kernel/generic/src/mm/as.c
- Timestamp:
- 2007-03-31T22:22:50Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 31d8e10
- Parents:
- 563c2dd
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/as.c
r563c2dd r879585a3 96 96 97 97 /** 98 * This lock protects inactive_as_with_asid_head list. It must be acquired 99 * before as_t mutex. 100 */ 101 SPINLOCK_INITIALIZE(inactive_as_with_asid_lock); 98 * This lock serializes access to the ASID subsystem. 99 * It protects: 100 * - inactive_as_with_asid_head list 101 * - as->asid for each as of the as_t type 102 * - asids_allocated counter 103 */ 104 SPINLOCK_INITIALIZE(asidlock); 102 105 103 106 /** … … 206 209 * it is safe not to lock its mutex. 207 210 */ 211 208 212 ipl = interrupts_disable(); 209 spinlock_lock(& inactive_as_with_asid_lock);213 spinlock_lock(&asidlock); 210 214 if (as->asid != ASID_INVALID && as != AS_KERNEL) { 211 215 if (as != AS && as->cpu_refcount == 0) … … 213 217 asid_put(as->asid); 214 218 } 215 spinlock_unlock(& inactive_as_with_asid_lock);219 spinlock_unlock(&asidlock); 216 220 217 221 /* … … 861 865 * 862 866 * Note that this function cannot sleep as it is essentially a part of 863 * scheduling. Sleeping here would lead to deadlock on wakeup. 867 * scheduling. Sleeping here would lead to deadlock on wakeup. Another 868 * thing which is forbidden in this context is locking the address space. 864 869 * 865 870 * @param old Old address space or NULL. … … 868 873 void as_switch(as_t *old_as, as_t *new_as) 869 874 { 870 ipl_t ipl; 871 bool needs_asid = false; 872 873 ipl = interrupts_disable(); 874 spinlock_lock(&inactive_as_with_asid_lock); 875 spinlock_lock(&asidlock); 875 876 876 877 /* … … 878 879 */ 879 880 if (old_as) { 880 mutex_lock_active(&old_as->lock);881 881 ASSERT(old_as->cpu_refcount); 882 882 if((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) { … … 891 891 &inactive_as_with_asid_head); 892 892 } 893 mutex_unlock(&old_as->lock);894 893 895 894 /* … … 903 902 * Second, prepare the new address space. 904 903 */ 905 mutex_lock_active(&new_as->lock);906 904 if ((new_as->cpu_refcount++ == 0) && (new_as != AS_KERNEL)) { 907 if (new_as->asid != ASID_INVALID) {905 if (new_as->asid != ASID_INVALID) 908 906 list_remove(&new_as->inactive_as_with_asid_link); 909 } else { 910 /* 911 * Defer call to asid_get() until new_as->lock is released. 912 */ 913 needs_asid = true; 914 } 907 else 908 new_as->asid = asid_get(); 915 909 } 916 910 #ifdef AS_PAGE_TABLE 917 911 SET_PTL0_ADDRESS(new_as->genarch.page_table); 918 912 #endif 919 mutex_unlock(&new_as->lock);920 921 if (needs_asid) {922 /*923 * Allocation of new ASID was deferred924 * until now in order to avoid deadlock.925 */926 asid_t asid;927 928 asid = asid_get();929 mutex_lock_active(&new_as->lock);930 new_as->asid = asid;931 mutex_unlock(&new_as->lock);932 }933 spinlock_unlock(&inactive_as_with_asid_lock);934 interrupts_restore(ipl);935 913 936 914 /* … … 939 917 */ 940 918 as_install_arch(new_as); 919 920 spinlock_unlock(&asidlock); 941 921 942 922 AS = new_as;
Note:
See TracChangeset
for help on using the changeset viewer.