Page MenuHomeFreeBSD

msi: report error from BUS_REMAP_INTR
ClosedPublic

Authored by emaste on Aug 14 2023, 8:42 PM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Jun 21, 12:37 AM
Unknown Object (File)
May 17 2024, 3:22 PM
Unknown Object (File)
May 17 2024, 3:22 PM
Unknown Object (File)
May 17 2024, 3:22 PM
Unknown Object (File)
May 17 2024, 3:22 PM
Unknown Object (File)
May 17 2024, 3:22 PM
Unknown Object (File)
May 17 2024, 3:22 PM
Unknown Object (File)
May 1 2024, 11:36 PM
Subscribers

Details

Summary

BUS_REMAP_INTR failing is likely non-fatal, resulting in a performance issue rather than a functional issue. However we should report failure so that bugs can be found and fixed.

Diff Detail

Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

emaste created this revision.

Have to have D41449 first or we'll have false warnings.

sys/x86/x86/msi.c
331

don't really want to do this if the BUS_REMAP_INTR failed as then we'll have no functional interrupt, but I am not sure of other tear-down we have to do (i.e., undoing Allocate IDT vectors) so I think the warning message is better than nothing

sys/x86/x86/msi.c
299

I think the extra cleanup would be:

if (msi->msi_intsrc.is_handlers > 0)
    apic_disable_vector(msi->msi_cpu, msi->msi_vector);
msi->msi_cpu = old_id;
msi->msi_vector = old_vector;
for (i = 1; i < msi->msi_count; i++) {
    sib = ....;
    if (sib->msi_intsrc.is_handlers > 0)
        apic_disable_vector(sib->msi_cpu, sib->msi_vector);
    sib->msi_cpu = old_id;
    sib->msi_cpu = old_vector + i;
}

for (i = 0; i < msi->msi_count; i++)
    apic_free_vector(apic_id, vector + i);
return (error);
sys/x86/x86/msi.c
299

However, what I would probably do instead, is to restructure this a bit so you avoid changing msi_cpu and msi_vector for the secondary vectors (sib) until after the REMAP returns success.

I would also move the bootverbose printfs after the REMAP as well.

untested attempt at @jhb's suggestion

sys/x86/x86/msi.c
294–295

I still need to do this prior to BUS_REMAP_INTR, yeah?

302–311

and the apic_disable_vector / apic_free_vector needs to be done after BUS_REMAP_INTR in the failing case

but, maybe I can set old_vector = vector and old_id = apic_id and use the same apic_disable_vector / apic_free_vector code

337

we're missing an apic_free_vector for old_vector, no?

337

oh, no we do it at line 330

Proposed commit message

msi: handle error from BUS_REMAP_INTR

Previously we silently ignored a failure from BUS_REMAP_INTR, which
would result in non-functional interrupts.

Now we allocate and enable new vectors, but postpone assignment of new
APIC IDs and vectors until after BUS_REMAP_INTR is successful.  We then
disable and free the old vectors.  If BUS_REMAP_INTR fails we leave the
old configuration intact, and disable and free the new, unused vectors.

Sponsored by:   The FreeBSD Foundation
sys/x86/x86/msi.c
297

The issue here I think is that this will call back into the MSI code and expects to see the "new" values in msi_cpu and msi_vector. You can defer updating them for all the siblings (sib), but the "main" MSI IRQ in the group you have to update before calling this.

300

So these two lines have to be before the BUS_REMAP_INTR call, and you have to undo them in the error case.

316–317

Might be a nicer error message?

318

So here you would insert:

msi->msi_cpu = old_id;
msi->msi_vector = old_vector;

before updating the old values.

move msi_cpu/msi_vector setting back before BUS_REMAP_INTR

Thanks for reworking this.

sys/x86/x86/msi.c
287
This revision is now accepted and ready to land.Aug 17 2023, 6:43 PM