Re: [PATCH 06/19] LoongArch: Add exception/interrupt handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jul 27, 2021 at 4:10 PM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:
> On Wed, Jul 07, 2021 at 11:56:37PM +1000, Nicholas Piggin wrote:
> > >> +/*
> > >> + * Common Vectored Interrupt
> > >> + * Complete the register saves and invoke the do_vi() handler
> > >> + */
> > >> +SYM_FUNC_START(except_vec_vi_handler)
> > >> +  la      t1, __arch_cpu_idle
> > >> +  LONG_L  t0, sp, PT_EPC
> > >> +  /* 32 byte rollback region */
> > >> +  ori     t0, t0, 0x1f
> > >> +  xori    t0, t0, 0x1f
> > >> +  bne     t0, t1, 1f
> > >> +  LONG_S  t0, sp, PT_EPC
> > >
> > > Seriously, you're having your interrupt handler recover from the idle
> > > race? On a *new* architecture?
> >
> > It's heavily derived from MIPS (does that make the wholesale replacement
> > of arch/mips copyright headers a bit questionable?).
> >
> > I don't think it's such a bad trick though -- restartable sequences
> > before they were cool. It can let you save an irq disable in some
> > cases (depending on the arch of course).
>
> In this case you're making *every* interrupt slower. Simply adding a new
> idle instruction, one that can be called with interrupts disabled and
> will terminate on a pending interrupt, would've solved the issues much
> nicer and reclaimed the cycles spend on this restart trick.

Are we actually sure that loongarch /needs/ this version?

The code was clearly copied from the mips default r4k_wait()
function, but mips also has this one:

/*
 * This variant is preferable as it allows testing need_resched and going to
 * sleep depending on the outcome atomically.  Unfortunately the "It is
 * implementation-dependent whether the pipeline restarts when a non-enabled
 * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
 * using this version a gamble.
 */
void __cpuidle r4k_wait_irqoff(void)
{
        if (!need_resched())
                __asm__(
                "       .set    push            \n"
                "       .set    arch=r4000      \n"
                "       wait                    \n"
                "       .set    pop             \n");
        raw_local_irq_enable();
}

        case CPU_LOONGSON64:
                if ((c->processor_id & (PRID_IMP_MASK | PRID_REV_MASK)) >=
                                (PRID_IMP_LOONGSON_64C |
PRID_REV_LOONGSON3A_R2_0) ||
                                (c->processor_id & PRID_IMP_MASK) ==
PRID_IMP_LOONGSON_64R)
                        cpu_wait = r4k_wait;
...
                cpu_wait = r4k_wait;
                if (read_c0_config7() & MIPS_CONF7_WII)
                        cpu_wait = r4k_wait_irqoff;
                if (cpu_has_mips_r6) {
                        cpu_wait = r4k_wait_irqoff;

So a lot of the newer mips variants already get the fixed
version. Maybe the hardware developers fixed it without telling
the kernel people about it?

         Arnd



[Index of Archives]     [Linux Kernel]     [Kernel Newbies]     [x86 Platform Driver]     [Netdev]     [Linux Wireless]     [Netfilter]     [Bugtraq]     [Linux Filesystems]     [Yosemite Discussion]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux