[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH xenbus 3/7] Generalize per-processor DPC in SYSTEM
From: Paul Durrant <pdurrant@xxxxxxxxxx> The DPC is currently used only for acquiring and display per-processor information but a subsequent patch will also use the DPC for another purpose. Hence this patch creates a general SystemProcessorDpc() call-back that then calls a slightly modified SystemProcessorInformation() (which is renamed SystemProcessorInitialize()) to fulfil the original purpose. This patch also adds a mechanism for the per-processor DPCs to pass back a status code to the main initialization code such that it can be aborted if any of them fail. A new SystemProcessorTeardown() function is added to do cleanup, and hence we can verify the SYSTEM_PROCESSOR structures are zeroed in SystemDeregisterProcessorChangeCallback(). Currently no failure is possible during SystemProcessorDpc() but this will change with the addition of a subsequent patch. NOTE: __SystemProcessorCount() is relocated earlier in system.c as it now needs to be called by SystemDeregisterProcessorChangeCallback(). It is relocated earlier than strictly necessary for this, but subsequent patches will do further function relocation and add additonal funcrtions that also rely on __SystemProcessorCount() being in its new position. Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx> --- src/xen/system.c | 179 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 133 insertions(+), 46 deletions(-) diff --git a/src/xen/system.c b/src/xen/system.c index 8219c86f8321..7bd7cb381f38 100644 --- a/src/xen/system.c +++ b/src/xen/system.c @@ -49,10 +49,12 @@ #define XEN_SYSTEM_TAG 'TSYS' typedef struct _SYSTEM_PROCESSOR { - KDPC Dpc; - CHAR Manufacturer[13]; - UCHAR ApicID; - UCHAR ProcessorID; + KDPC Dpc; + CHAR Manufacturer[13]; + UCHAR ApicID; + UCHAR ProcessorID; + NTSTATUS Status; + KEVENT Event; } SYSTEM_PROCESSOR, *PSYSTEM_PROCESSOR; typedef struct _SYSTEM_WATCHDOG { @@ -562,37 +564,18 @@ done: Info("<====\n"); } -static -_Function_class_(KDEFERRED_ROUTINE) -_IRQL_requires_max_(DISPATCH_LEVEL) -_IRQL_requires_min_(DISPATCH_LEVEL) -_IRQL_requires_(DISPATCH_LEVEL) -_IRQL_requires_same_ -VOID -SystemProcessorInformation( - IN PKDPC Dpc, - IN PVOID _Context, - IN PVOID Argument1, - IN PVOID Argument2 +static VOID +SystemProcessorInitialize( + IN ULONG Cpu ) { PSYSTEM_CONTEXT Context = &SystemContext; - PKEVENT Event = Argument1; - ULONG Cpu; - PROCESSOR_NUMBER ProcNumber; PSYSTEM_PROCESSOR Processor; ULONG EAX; ULONG EBX; ULONG ECX; ULONG EDX; - UNREFERENCED_PARAMETER(Dpc); - UNREFERENCED_PARAMETER(_Context); - UNREFERENCED_PARAMETER(Argument2); - - Cpu = KeGetCurrentProcessorNumberEx(&ProcNumber); - ASSERT3U(Cpu, <, Context->ProcessorCount); - Processor = &Context->Processor[Cpu]; if (Cpu == 0) { @@ -609,8 +592,6 @@ SystemProcessorInformation( SystemViridianInformation(EAX - 0x40000000); } - Info("====> (%u:%u)\n", ProcNumber.Group, ProcNumber.Number); - __CpuId(0, NULL, &EBX, &ECX, &EDX); RtlCopyMemory(&Processor->Manufacturer[0], &EBX, sizeof (ULONG)); @@ -625,10 +606,73 @@ SystemProcessorInformation( Info("Manufacturer: %s\n", Processor->Manufacturer); Info("APIC ID: %02X\n", Processor->ApicID); Info("PROCESSOR ID: %02X\n", Processor->ProcessorID); +} + +static VOID +SystemProcessorTeardown( + IN ULONG Cpu + ) +{ + PSYSTEM_CONTEXT Context = &SystemContext; + PSYSTEM_PROCESSOR Processor; - KeSetEvent(Event, IO_NO_INCREMENT, FALSE); + Processor = &Context->Processor[Cpu]; + + Processor->ProcessorID = 0; + Processor->ApicID = 0; + RtlZeroMemory(Processor->Manufacturer, sizeof (Processor->Manufacturer)); +} + +static FORCEINLINE ULONG +__SystemProcessorCount( + VOID + ) +{ + PSYSTEM_CONTEXT Context = &SystemContext; + + KeMemoryBarrier(); + + return Context->ProcessorCount; +} + +static +_Function_class_(KDEFERRED_ROUTINE) +_IRQL_requires_max_(DISPATCH_LEVEL) +_IRQL_requires_min_(DISPATCH_LEVEL) +_IRQL_requires_(DISPATCH_LEVEL) +_IRQL_requires_same_ +VOID +SystemProcessorDpc( + IN PKDPC Dpc, + IN PVOID _Context, + IN PVOID Argument1, + IN PVOID Argument2 + ) +{ + PSYSTEM_CONTEXT Context = &SystemContext; + ULONG Cpu; + PROCESSOR_NUMBER ProcNumber; + PSYSTEM_PROCESSOR Processor; + + UNREFERENCED_PARAMETER(Dpc); + UNREFERENCED_PARAMETER(_Context); + UNREFERENCED_PARAMETER(Argument1); + UNREFERENCED_PARAMETER(Argument2); + + Cpu = KeGetCurrentProcessorNumberEx(&ProcNumber); + ASSERT3U(Cpu, <, Context->ProcessorCount); + + Processor = &Context->Processor[Cpu]; + Processor->Status = STATUS_UNSUCCESSFUL; + + Info("====> (%u:%u)\n", ProcNumber.Group, ProcNumber.Number); + + SystemProcessorInitialize(Cpu); Info("<==== (%u:%u)\n", ProcNumber.Group, ProcNumber.Number); + + Processor->Status = STATUS_SUCCESS; + KeSetEvent(&Processor->Event, IO_NO_INCREMENT, FALSE); } static @@ -690,21 +734,24 @@ SystemProcessorChangeCallback( } case KeProcessorAddCompleteNotify: { PSYSTEM_PROCESSOR Processor; - KEVENT Event; ASSERT3U(Cpu, <, Context->ProcessorCount); Processor = &Context->Processor[Cpu]; - KeInitializeEvent(&Event, NotificationEvent, FALSE); + KeInitializeEvent(&Processor->Event, NotificationEvent, FALSE); - KeInitializeDpc(&Processor->Dpc, SystemProcessorInformation, NULL); + KeInitializeDpc(&Processor->Dpc, SystemProcessorDpc, NULL); KeSetImportanceDpc(&Processor->Dpc, HighImportance); KeSetTargetProcessorDpcEx(&Processor->Dpc, &ProcNumber); - KeInsertQueueDpc(&Processor->Dpc, &Event, NULL); + KeInsertQueueDpc(&Processor->Dpc, NULL, NULL); - (VOID) KeWaitForSingleObject(&Event, + // + // Wait for the DPC to avoid log lines from multiple processor + // initializations from being interleaved. + // + (VOID) KeWaitForSingleObject(&Processor->Event, Executive, KernelMode, FALSE, @@ -758,10 +805,23 @@ SystemDeregisterProcessorChangeCallback( ) { PSYSTEM_CONTEXT Context = &SystemContext; + ULONG Cpu; KeDeregisterProcessorChangeCallback(Context->ProcessorChangeHandle); Context->ProcessorChangeHandle = NULL; + for (Cpu = 0; Cpu < __SystemProcessorCount(); Cpu++) { + PSYSTEM_PROCESSOR Processor = &Context->Processor[Cpu]; + + SystemProcessorTeardown(Cpu); + + RtlZeroMemory(&Processor->Dpc, sizeof (KDPC)); + RtlZeroMemory(&Processor->Event, sizeof (KEVENT)); + Processor->Status = 0; + + ASSERT(IsZeroMemory(Processor, sizeof (SYSTEM_PROCESSOR))); + } + __SystemFree(Context->Processor); Context->Processor = NULL; Context->ProcessorCount = 0; @@ -964,6 +1024,38 @@ fail1: return status; } +static NTSTATUS +SystemCheckProcessors( + VOID + ) +{ + PSYSTEM_CONTEXT Context = &SystemContext; + ULONG Cpu; + NTSTATUS status; + + for (Cpu = 0; Cpu < __SystemProcessorCount(); Cpu++) + { + PSYSTEM_PROCESSOR Processor = &Context->Processor[Cpu]; + + (VOID) KeWaitForSingleObject(&Processor->Event, + Executive, + KernelMode, + FALSE, + NULL); + + status = Processor->Status; + if (!NT_SUCCESS(status)) + goto fail1; + } + + return STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", status); + + return status; +} + NTSTATUS SystemInitialize( VOID @@ -1007,8 +1099,15 @@ SystemInitialize( if (!NT_SUCCESS(status)) goto fail8; + status = SystemCheckProcessors(); + if (!NT_SUCCESS(status)) + goto fail9; + return STATUS_SUCCESS; +fail9: + Error("fail9\n"); + fail8: Error("fail8\n"); @@ -1045,18 +1144,6 @@ fail1: return status; } -static FORCEINLINE ULONG -__SystemProcessorCount( - VOID - ) -{ - PSYSTEM_CONTEXT Context = &SystemContext; - - KeMemoryBarrier(); - - return Context->ProcessorCount; -} - XEN_API ULONG SystemProcessorCount( -- 2.17.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |