Changeset 38dc82d in mainline for kernel/arch


Ignore:
Timestamp:
2016-08-31T14:16:45Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
346b12a2
Parents:
dc05a9a
Message:

Make page_mapping_find() return a copy rather than the actual PTE

This makes page_mapping_find() more suitable for use with lock-free data
structures such as CHT that guarantee existence of the data only for
some limited time while a condition holds (e.g. inside of a RCU-protected
critical section that must be around all CHT lookups).

Location:
kernel/arch
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia64/src/mm/tlb.c

    rdc05a9a r38dc82d  
    484484{
    485485        uintptr_t va;
    486         pte_t *t;
     486        pte_t t;
    487487       
    488488        va = istate->cr_ifa; /* faulting address */
     
    490490        ASSERT(!is_kernel_fault(va));
    491491
    492         t = page_mapping_find(AS, va, true);
    493         if (t) {
     492        bool found = page_mapping_find(AS, va, true, &t);
     493        if (found) {
    494494                /*
    495495                 * The mapping was found in software page hash table.
    496496                 * Insert it into data translation cache.
    497497                 */
    498                 itc_pte_copy(t);
     498                itc_pte_copy(&t);
    499499        } else {
    500500                /*
     
    600600       
    601601       
    602         pte_t *entry = page_mapping_find(as, va, true);
    603         if (entry) {
     602        pte_t t;
     603        bool found = page_mapping_find(as, va, true, &t);
     604        if (found) {
    604605                /*
    605606                 * The mapping was found in the software page hash table.
    606607                 * Insert it into data translation cache.
    607608                 */
    608                 dtc_pte_copy(entry);
     609                dtc_pte_copy(&t);
    609610        } else {
    610611                if (try_memmap_io_insertion(va, istate))
     
    641642{
    642643        uintptr_t va;
    643         pte_t *t;
     644        pte_t t;
    644645        as_t *as = AS;
    645646       
     
    649650                as = AS_KERNEL;
    650651
    651         t = page_mapping_find(as, va, true);
    652         ASSERT((t) && (t->p));
    653         if ((t) && (t->p) && (t->w)) {
     652        bool found = page_mapping_find(as, va, true, &t);
     653
     654        ASSERT(found);
     655        ASSERT(t.p);
     656
     657        if (found && t.p && t.w) {
    654658                /*
    655659                 * Update the Dirty bit in page tables and reinsert
    656660                 * the mapping into DTC.
    657661                 */
    658                 t->d = true;
    659                 dtc_pte_copy(t);
     662                t.d = true;
     663                dtc_pte_copy(&t);
    660664        } else {
    661665                as_page_fault(va, PF_ACCESS_WRITE, istate);
     
    672676{
    673677        uintptr_t va;
    674         pte_t *t;
     678        pte_t t;
    675679       
    676680        va = istate->cr_ifa;  /* faulting address */
     
    678682        ASSERT(!is_kernel_fault(va));
    679683       
    680         t = page_mapping_find(AS, va, true);
    681         ASSERT((t) && (t->p));
    682         if ((t) && (t->p) && (t->x)) {
     684        bool found = page_mapping_find(AS, va, true, &t);
     685
     686        ASSERT(found);
     687        ASSERT(t.p);
     688
     689        if (found && t.p && t.x) {
    683690                /*
    684691                 * Update the Accessed bit in page tables and reinsert
    685692                 * the mapping into ITC.
    686693                 */
    687                 t->a = true;
    688                 itc_pte_copy(t);
     694                t.a = true;
     695                itc_pte_copy(&t);
    689696        } else {
    690697                as_page_fault(va, PF_ACCESS_EXEC, istate);
     
    701708{
    702709        uintptr_t va;
    703         pte_t *t;
     710        pte_t t;
    704711        as_t *as = AS;
    705712       
     
    709716                as = AS_KERNEL;
    710717
    711         t = page_mapping_find(as, va, true);
    712         ASSERT((t) && (t->p));
    713         if ((t) && (t->p)) {
     718        bool found = page_mapping_find(as, va, true, &t);
     719
     720        ASSERT(found);
     721        ASSERT(t.p);
     722
     723        if (found && t.p) {
    714724                /*
    715725                 * Update the Accessed bit in page tables and reinsert
    716726                 * the mapping into DTC.
    717727                 */
    718                 t->a = true;
    719                 dtc_pte_copy(t);
     728                t.a = true;
     729                dtc_pte_copy(&t);
    720730        } else {
    721731                if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
     
    736746{
    737747        uintptr_t va;
    738         pte_t *t;
     748        pte_t t;
    739749       
    740750        va = istate->cr_ifa;  /* faulting address */
     
    745755         * Assume a write to a read-only page.
    746756         */
    747         t = page_mapping_find(AS, va, true);
    748         ASSERT((t) && (t->p));
    749         ASSERT(!t->w);
     757        bool found = page_mapping_find(AS, va, true, &t);
     758
     759        ASSERT(found);
     760        ASSERT(t.p);
     761        ASSERT(!t.w);
     762
    750763        as_page_fault(va, PF_ACCESS_WRITE, istate);
    751764}
     
    760773{
    761774        uintptr_t va;
    762         pte_t *t;
     775        pte_t t;
    763776       
    764777        va = istate->cr_ifa;  /* faulting address */
     
    766779        ASSERT(!is_kernel_fault(va));
    767780
    768         t = page_mapping_find(AS, va, true);
    769         ASSERT(t);
    770        
    771         if (t->p) {
     781        bool found = page_mapping_find(AS, va, true, &t);
     782
     783        ASSERT(found);
     784       
     785        if (t.p) {
    772786                /*
    773787                 * If the Present bit is set in page hash table, just copy it
    774788                 * and update ITC/DTC.
    775789                 */
    776                 if (t->x)
    777                         itc_pte_copy(t);
     790                if (t.x)
     791                        itc_pte_copy(&t);
    778792                else
    779                         dtc_pte_copy(t);
     793                        dtc_pte_copy(&t);
    780794        } else {
    781795                as_page_fault(va, PF_ACCESS_READ, istate);
  • kernel/arch/mips32/src/mm/tlb.c

    rdc05a9a r38dc82d  
    9797        entry_lo_t lo;
    9898        uintptr_t badvaddr;
    99         pte_t *pte;
     99        pte_t pte;
    100100       
    101101        badvaddr = cp0_badvaddr_read();
    102102
    103         pte = page_mapping_find(AS, badvaddr, true);
    104         if (pte && pte->p) {
     103        bool found = page_mapping_find(AS, badvaddr, true, &pte);
     104        if (found && pte.p) {
    105105                /*
    106106                 * Record access to PTE.
    107107                 */
    108                 pte->a = 1;
    109 
    110                 tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d,
    111                     pte->cacheable, pte->pfn);
     108                pte.a = 1;
     109
     110                tlb_prepare_entry_lo(&lo, pte.g, pte.p, pte.d,
     111                    pte.cacheable, pte.pfn);
    112112
    113113                /*
     
    138138        tlb_index_t index;
    139139        uintptr_t badvaddr;
    140         pte_t *pte;
     140        pte_t pte;
    141141
    142142        /*
     
    162162        badvaddr = cp0_badvaddr_read();
    163163
    164         pte = page_mapping_find(AS, badvaddr, true);
    165         if (pte && pte->p) {
     164        bool found = page_mapping_find(AS, badvaddr, true, &pte);
     165        if (found && pte.p) {
    166166                /*
    167167                 * Read the faulting TLB entry.
     
    172172                 * Record access to PTE.
    173173                 */
    174                 pte->a = 1;
    175 
    176                 tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d,
    177                     pte->cacheable, pte->pfn);
     174                pte.a = 1;
     175
     176                tlb_prepare_entry_lo(&lo, pte.g, pte.p, pte.d,
     177                    pte.cacheable, pte.pfn);
    178178
    179179                /*
     
    200200        tlb_index_t index;
    201201        uintptr_t badvaddr;
    202         pte_t *pte;
     202        pte_t pte;
    203203
    204204        badvaddr = cp0_badvaddr_read();
     
    224224        }
    225225
    226         pte = page_mapping_find(AS, badvaddr, true);
    227         if (pte && pte->p && pte->w) {
     226        bool found = page_mapping_find(AS, badvaddr, true, &pte);
     227        if (found && pte.p && pte.w) {
    228228                /*
    229229                 * Read the faulting TLB entry.
     
    234234                 * Record access and write to PTE.
    235235                 */
    236                 pte->a = 1;
    237                 pte->d = 1;
    238 
    239                 tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w,
    240                     pte->cacheable, pte->pfn);
     236                pte.a = 1;
     237                pte.d = 1;
     238
     239                tlb_prepare_entry_lo(&lo, pte.g, pte.p, pte.w,
     240                    pte.cacheable, pte.pfn);
    241241
    242242                /*
  • kernel/arch/ppc32/src/mm/pht.c

    rdc05a9a r38dc82d  
    4949 * @param access   Access mode that caused the fault.
    5050 * @param istate   Pointer to interrupted state.
    51  *
    52  * @return PTE on success, NULL otherwise.
    53  *
    54  */
    55 static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
    56     istate_t *istate)
     51 * @param[out] pte Structure that will receive a copy of the found PTE.
     52 *
     53 * @return True if the mapping was found, false otherwise.
     54 *
     55 */
     56static bool find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
     57    istate_t *istate, pte_t *pte)
    5758{
    5859        /*
    5960         * Check if the mapping exists in page tables.
    6061         */
    61         pte_t *pte = page_mapping_find(as, badvaddr, true);
    62         if ((pte) && (pte->present)) {
     62        bool found = page_mapping_find(as, badvaddr, true, pte);
     63        if (found && pte->present) {
    6364                /*
    6465                 * Mapping found in page tables.
    6566                 * Immediately succeed.
    6667                 */
    67                 return pte;
     68                return true;
    6869        }
    6970        /*
     
    7677                 * The mapping ought to be in place.
    7778                 */
    78                 pte = page_mapping_find(as, badvaddr, true);
    79                 ASSERT((pte) && (pte->present));
    80                 return pte;
    81         }
    82 
    83         return NULL;
     79                found = page_mapping_find(as, badvaddr, true, pte);
     80
     81                ASSERT(found);
     82                ASSERT(pte->present);
     83
     84                return found;
     85        }
     86
     87        return false;
    8488}
    8589
     
    182186                badvaddr = istate->pc;
    183187       
    184         pte_t *pte = find_mapping_and_check(AS, badvaddr,
    185             PF_ACCESS_READ /* FIXME */, istate);
    186        
    187         if (pte) {
     188        pte_t pte;
     189        bool found = find_mapping_and_check(AS, badvaddr,
     190            PF_ACCESS_READ /* FIXME */, istate, &pte);
     191       
     192        if (found) {
    188193                /* Record access to PTE */
    189                 pte->accessed = 1;
    190                 pht_insert(badvaddr, pte);
     194                pte.accessed = 1;
     195                pht_insert(badvaddr, &pte);
    191196        }
    192197}
  • kernel/arch/sparc64/src/mm/sun4u/tlb.c

    rdc05a9a r38dc82d  
    197197{
    198198        size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
    199         pte_t *t;
    200 
    201         t = page_mapping_find(AS, istate->tpc, true);
    202         if (t && PTE_EXECUTABLE(t)) {
     199        pte_t t;
     200
     201        bool found = page_mapping_find(AS, istate->tpc, true, &t);
     202        if (found && PTE_EXECUTABLE(&t)) {
    203203                /*
    204204                 * The mapping was found in the software page hash table.
    205205                 * Insert it into ITLB.
    206206                 */
    207                 t->a = true;
    208                 itlb_pte_copy(t, index);
     207                t.a = true;
     208                itlb_pte_copy(&t, index);
    209209#ifdef CONFIG_TSB
    210                 itsb_pte_copy(t, index);
     210                itsb_pte_copy(&t, index);
    211211#endif
    212212        } else {
     
    233233        uintptr_t page_16k;
    234234        size_t index;
    235         pte_t *t;
     235        pte_t t;
    236236        as_t *as = AS;
    237237
     
    253253        }
    254254
    255         t = page_mapping_find(as, page_16k, true);
    256         if (t) {
     255        bool found = page_mapping_find(as, page_16k, true, &t);
     256        if (found) {
    257257                /*
    258258                 * The mapping was found in the software page hash table.
    259259                 * Insert it into DTLB.
    260260                 */
    261                 t->a = true;
    262                 dtlb_pte_copy(t, index, true);
     261                t.a = true;
     262                dtlb_pte_copy(&t, index, true);
    263263#ifdef CONFIG_TSB
    264                 dtsb_pte_copy(t, index, true);
     264                dtsb_pte_copy(&t, index, true);
    265265#endif
    266266        } else {
     
    283283        uintptr_t page_16k;
    284284        size_t index;
    285         pte_t *t;
     285        pte_t t;
    286286        as_t *as = AS;
    287287
     
    293293                as = AS_KERNEL;
    294294
    295         t = page_mapping_find(as, page_16k, true);
    296         if (t && PTE_WRITABLE(t)) {
     295        bool found = page_mapping_find(as, page_16k, true, &t);
     296        if (found && PTE_WRITABLE(&t)) {
    297297                /*
    298298                 * The mapping was found in the software page hash table and is
     
    300300                 * into DTLB.
    301301                 */
    302                 t->a = true;
    303                 t->d = true;
     302                t.a = true;
     303                t.d = true;
    304304                dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
    305305                    page_16k + index * MMU_PAGE_SIZE);
    306                 dtlb_pte_copy(t, index, false);
     306                dtlb_pte_copy(&t, index, false);
    307307#ifdef CONFIG_TSB
    308                 dtsb_pte_copy(t, index, false);
     308                dtsb_pte_copy(&t, index, false);
    309309#endif
    310310        } else {
  • kernel/arch/sparc64/src/mm/sun4v/tlb.c

    rdc05a9a r38dc82d  
    211211{
    212212        uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
    213         pte_t *t;
    214 
    215         t = page_mapping_find(AS, va, true);
    216 
    217         if (t && PTE_EXECUTABLE(t)) {
     213        pte_t t;
     214
     215        bool found = page_mapping_find(AS, va, true, &t);
     216        if (found && PTE_EXECUTABLE(&t)) {
    218217                /*
    219218                 * The mapping was found in the software page hash table.
    220219                 * Insert it into ITLB.
    221220                 */
    222                 t->a = true;
    223                 itlb_pte_copy(t);
     221                t.a = true;
     222                itlb_pte_copy(&t);
    224223#ifdef CONFIG_TSB
    225                 itsb_pte_copy(t);
     224                itsb_pte_copy(&t);
    226225#endif
    227226        } else {
     
    244243void fast_data_access_mmu_miss(unsigned int tt, istate_t *istate)
    245244{
    246         pte_t *t;
     245        pte_t t;
    247246        uintptr_t va = DMISS_ADDRESS(istate->tlb_tag_access);
    248247        uint16_t ctx = DMISS_CONTEXT(istate->tlb_tag_access);
     
    261260        }
    262261
    263         t = page_mapping_find(as, va, true);
    264         if (t) {
     262        bool found = page_mapping_find(as, va, true, &t);
     263        if (found) {
    265264                /*
    266265                 * The mapping was found in the software page hash table.
    267266                 * Insert it into DTLB.
    268267                 */
    269                 t->a = true;
    270                 dtlb_pte_copy(t, true);
     268                t.a = true;
     269                dtlb_pte_copy(&t, true);
    271270#ifdef CONFIG_TSB
    272                 dtsb_pte_copy(t, true);
     271                dtsb_pte_copy(&t, true);
    273272#endif
    274273        } else {
     
    288287void fast_data_access_protection(unsigned int tt, istate_t *istate)
    289288{
    290         pte_t *t;
     289        pte_t t;
    291290        uintptr_t va = DMISS_ADDRESS(istate->tlb_tag_access);
    292291        uint16_t ctx = DMISS_CONTEXT(istate->tlb_tag_access);
     
    296295                as = AS_KERNEL;
    297296
    298         t = page_mapping_find(as, va, true);
    299         if (t && PTE_WRITABLE(t)) {
     297        bool found = page_mapping_find(as, va, true, &t);
     298        if (found && PTE_WRITABLE(&t)) {
    300299                /*
    301300                 * The mapping was found in the software page hash table and is
     
    303302                 * into DTLB.
    304303                 */
    305                 t->a = true;
    306                 t->d = true;
     304                t.a = true;
     305                t.d = true;
    307306                mmu_demap_page(va, ctx, MMU_FLAG_DTLB);
    308                 dtlb_pte_copy(t, false);
     307                dtlb_pte_copy(&t, false);
    309308#ifdef CONFIG_TSB
    310                 dtsb_pte_copy(t, false);
     309                dtsb_pte_copy(&t, false);
    311310#endif
    312311        } else {
Note: See TracChangeset for help on using the changeset viewer.