Changeset 06f81c4 in mainline


Ignore:
Timestamp:
2023-04-16T13:00:39Z (20 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d8581611, f3dbe27
Parents:
fbaf6ac
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-03-28 16:21:30)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-04-16 13:00:39)
Message:

Check cpu_t::fpu_owner directly instead of thread_t::fpu_context_engaged

This results in net reduction in locking.

Location:
kernel/generic
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/cpu.h

    rfbaf6ac r06f81c4  
    9797        cpu_arch_t arch;
    9898
     99#ifdef CONFIG_FPU_LAZY
    99100        IRQ_SPINLOCK_DECLARE(fpu_lock);
    100101        struct thread *fpu_owner;
     102#endif
    101103
    102104        /**
  • kernel/generic/include/proc/thread.h

    rfbaf6ac r06f81c4  
    132132        bool fpu_context_exists;
    133133
    134         /*
    135          * Defined only if thread doesn't run.
    136          * It means that fpu context is in CPU that last time executes this
    137          * thread. This disables migration.
    138          */
    139         bool fpu_context_engaged;
    140 
    141134        /* The thread will not be migrated if nomigrate is non-zero. */
    142135        unsigned int nomigrate;
  • kernel/generic/src/cpu/cpu.c

    rfbaf6ac r06f81c4  
    8484                        cpus[i].id = i;
    8585
     86#ifdef CONFIG_FPU_LAZY
    8687                        irq_spinlock_initialize(&cpus[i].fpu_lock, "cpus[].fpu_lock");
     88#endif
    8789                        irq_spinlock_initialize(&cpus[i].tlb_lock, "cpus[].tlb_lock");
    8890
  • kernel/generic/src/proc/scheduler.c

    rfbaf6ac r06f81c4  
    8484
    8585#ifdef CONFIG_FPU_LAZY
     86        irq_spinlock_lock(&CPU->fpu_lock, true);
     87
    8688        if (THREAD == CPU->fpu_owner)
    8789                fpu_enable();
    8890        else
    8991                fpu_disable();
     92
     93        irq_spinlock_unlock(&CPU->fpu_lock, true);
    9094#elif defined CONFIG_FPU
    9195        fpu_enable();
     
    133137        /* Save old context */
    134138        if (CPU->fpu_owner != NULL) {
    135                 irq_spinlock_lock(&CPU->fpu_owner->lock, false);
    136139                fpu_context_save(&CPU->fpu_owner->fpu_context);
    137 
    138                 /* Don't prevent migration */
    139                 CPU->fpu_owner->fpu_context_engaged = false;
    140                 irq_spinlock_unlock(&CPU->fpu_owner->lock, false);
    141140                CPU->fpu_owner = NULL;
    142141        }
    143142
    144         irq_spinlock_lock(&THREAD->lock, false);
    145143        if (THREAD->fpu_context_exists) {
    146144                fpu_context_restore(&THREAD->fpu_context);
     
    151149
    152150        CPU->fpu_owner = THREAD;
    153         THREAD->fpu_context_engaged = true;
    154         irq_spinlock_unlock(&THREAD->lock, false);
    155151
    156152        irq_spinlock_unlock(&CPU->fpu_lock, false);
     
    503499#ifdef CONFIG_SMP
    504500
     501static inline void fpu_owner_lock(cpu_t *cpu)
     502{
     503#ifdef CONFIG_FPU_LAZY
     504        irq_spinlock_lock(&cpu->fpu_lock, false);
     505#endif
     506}
     507
     508static inline void fpu_owner_unlock(cpu_t *cpu)
     509{
     510#ifdef CONFIG_FPU_LAZY
     511        irq_spinlock_unlock(&cpu->fpu_lock, false);
     512#endif
     513}
     514
     515static inline thread_t *fpu_owner(cpu_t *cpu)
     516{
     517#ifdef CONFIG_FPU_LAZY
     518        assert(irq_spinlock_locked(&cpu->fpu_lock));
     519        return cpu->fpu_owner;
     520#else
     521        return NULL;
     522#endif
     523}
     524
    505525static thread_t *steal_thread_from(cpu_t *old_cpu, int i)
    506526{
     
    508528        runq_t *new_rq = &CPU->rq[i];
    509529
    510         irq_spinlock_lock(&old_rq->lock, true);
     530        ipl_t ipl = interrupts_disable();
     531
     532        fpu_owner_lock(old_cpu);
     533        irq_spinlock_lock(&old_rq->lock, false);
    511534
    512535        /* Search rq from the back */
     
    521544                 * FPU context is still in the CPU.
    522545                 */
    523                 if (thread->stolen || thread->nomigrate || thread->fpu_context_engaged) {
     546                if (thread->stolen || thread->nomigrate ||
     547                    thread == fpu_owner(old_cpu)) {
    524548                        irq_spinlock_unlock(&thread->lock, false);
    525549                        continue;
    526550                }
     551
     552                fpu_owner_unlock(old_cpu);
    527553
    528554                thread->stolen = true;
     
    546572                old_rq->n--;
    547573                list_remove(&thread->rq_link);
    548 
    549                 irq_spinlock_pass(&old_rq->lock, &new_rq->lock);
     574                irq_spinlock_unlock(&old_rq->lock, false);
    550575
    551576                /* Append thread to local queue. */
     577                irq_spinlock_lock(&new_rq->lock, false);
    552578                list_append(&thread->rq_link, &new_rq->rq);
    553579                new_rq->n++;
    554 
    555                 irq_spinlock_unlock(&new_rq->lock, true);
     580                irq_spinlock_unlock(&new_rq->lock, false);
    556581
    557582                atomic_dec(&old_cpu->nrdy);
    558583                atomic_inc(&CPU->nrdy);
    559 
     584                interrupts_restore(ipl);
    560585                return thread;
    561586        }
    562587
    563         irq_spinlock_unlock(&old_rq->lock, true);
     588        irq_spinlock_unlock(&old_rq->lock, false);
     589        fpu_owner_unlock(old_cpu);
     590        interrupts_restore(ipl);
    564591        return NULL;
    565592}
  • kernel/generic/src/proc/thread.c

    rfbaf6ac r06f81c4  
    355355
    356356        thread->fpu_context_exists = false;
    357         thread->fpu_context_engaged = false;
    358357
    359358        odlink_initialize(&thread->lthreads);
Note: See TracChangeset for help on using the changeset viewer.