Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 402eda5 in mainline


Ignore:
Timestamp:
2010-06-22T12:19:45Z (11 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
9539be6
Parents:
a49a1a1
Message:

Fix a newly introduced deadlock in the TLB shootdown algorithm.

Location:
kernel
Files:
4 edited

Legend:

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

    ra49a1a1 r402eda5  
    126126                 * Get the system rid of the stolen ASID.
    127127                 */
    128                 tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
     128                ipl_t ipl = tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
    129129                tlb_invalidate_asid(asid);
    130                 tlb_shootdown_finalize();
     130                tlb_shootdown_finalize(ipl);
    131131        } else {
    132132
     
    142142                 * Purge the allocated ASID from TLBs.
    143143                 */
    144                 tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
     144                ipl_t ipl = tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
    145145                tlb_invalidate_asid(asid);
    146                 tlb_shootdown_finalize();
     146                tlb_shootdown_finalize(ipl);
    147147        }
    148148       
  • kernel/generic/include/mm/tlb.h

    ra49a1a1 r402eda5  
    6868
    6969#ifdef CONFIG_SMP
    70 extern void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
    71     uintptr_t page, size_t count);
    72 extern void tlb_shootdown_finalize(void);
     70extern ipl_t tlb_shootdown_start(tlb_invalidate_type_t, asid_t, uintptr_t,
     71    size_t);
     72extern void tlb_shootdown_finalize(ipl_t);
    7373extern void tlb_shootdown_ipi_recv(void);
    7474#else
    75 #define tlb_shootdown_start(w, x, y, z)
    76 #define tlb_shootdown_finalize()
     75#define tlb_shootdown_start(w, x, y, z) (0)
     76#define tlb_shootdown_finalize(i)       ((i) = (i));
    7777#define tlb_shootdown_ipi_recv()
    7878#endif /* CONFIG_SMP */
     
    8484
    8585extern void tlb_invalidate_all(void);
    86 extern void tlb_invalidate_asid(asid_t asid);
    87 extern void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt);
     86extern void tlb_invalidate_asid(asid_t);
     87extern void tlb_invalidate_pages(asid_t, uintptr_t, size_t);
    8888#endif
    8989
  • kernel/generic/src/mm/as.c

    ra49a1a1 r402eda5  
    433433                 *
    434434                 */
    435                 tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base +
    436                     pages * PAGE_SIZE, area->pages - pages);
     435                ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
     436                    area->base + pages * PAGE_SIZE, area->pages - pages);
    437437               
    438438                /*
     
    528528                as_invalidate_translation_cache(as, area->base +
    529529                    pages * PAGE_SIZE, area->pages - pages);
    530                 tlb_shootdown_finalize();
     530                tlb_shootdown_finalize(ipl);
    531531               
    532532                page_table_unlock(as, false);
     
    578578         * Start TLB shootdown sequence.
    579579         */
    580         tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
     580        ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
     581            area->pages);
    581582       
    582583        /*
     
    625626         */
    626627        as_invalidate_translation_cache(as, area->base, area->pages);
    627         tlb_shootdown_finalize();
     628        tlb_shootdown_finalize(ipl);
    628629       
    629630        page_table_unlock(as, false);
     
    865866         *
    866867         */
    867         tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
     868        ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
     869            area->pages);
    868870       
    869871        /*
     
    912914         */
    913915        as_invalidate_translation_cache(as, area->base, area->pages);
    914         tlb_shootdown_finalize();
     916        tlb_shootdown_finalize(ipl);
    915917       
    916918        page_table_unlock(as, false);
  • kernel/generic/src/mm/tlb.c

    ra49a1a1 r402eda5  
    7373 * to all other processors.
    7474 *
    75  * @param type Type describing scope of shootdown.
    76  * @param asid Address space, if required by type.
    77  * @param page Virtual page address, if required by type.
    78  * @param count Number of pages, if required by type.
     75 * @param type          Type describing scope of shootdown.
     76 * @param asid          Address space, if required by type.
     77 * @param page          Virtual page address, if required by type.
     78 * @param count         Number of pages, if required by type.
    7979 *
     80 * @return The interrupt priority level as it existed prior to this call.
    8081 */
    81 void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
     82ipl_t tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
    8283    uintptr_t page, size_t count)
    8384{
     85        ipl_t ipl;
     86
     87        ipl = interrupts_disable();
    8488        CPU->tlb_active = false;
    85         irq_spinlock_lock(&tlblock, true);
     89        irq_spinlock_lock(&tlblock, false);
    8690       
    8791        size_t i;
     
    123127                if (cpus[i].tlb_active)
    124128                        goto busy_wait;
     129
     130        return ipl;
    125131}
    126132
    127133/** Finish TLB shootdown sequence.
    128134 *
     135 * @param ipl           Previous interrupt priority level.
    129136 */
    130 void tlb_shootdown_finalize(void)
     137void tlb_shootdown_finalize(ipl_t ipl)
    131138{
    132         irq_spinlock_unlock(&tlblock, true);
     139        irq_spinlock_unlock(&tlblock, false);
    133140        CPU->tlb_active = true;
     141        interrupts_restore(ipl);
    134142}
    135143
Note: See TracChangeset for help on using the changeset viewer.