public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Laszlo Ersek <lersek@redhat.com>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
	Leif Lindholm <leif.lindholm@linaro.org>
Subject: Re: [PATCH 13/15] ArmVirtPkg: implement ArmVirtMemInfo PPI, PEIM and library
Date: Tue, 21 Nov 2017 20:32:14 +0000	[thread overview]
Message-ID: <CAKv+Gu_mRmrVh+2TiiWWqZ_OOVj-KzaqqdnLzPeanWorRvBb7Q@mail.gmail.com> (raw)
In-Reply-To: <4e079219-e2e1-20b1-6772-97249925a4bf@redhat.com>

On 21 November 2017 at 20:17, Laszlo Ersek <lersek@redhat.com> wrote:
> On 11/21/17 18:57, Ard Biesheuvel wrote:
>>
>>
>>> On 21 Nov 2017, at 17:49, Laszlo Ersek <lersek@redhat.com> wrote:
>>>
>>>> On 11/17/17 17:09, Ard Biesheuvel wrote:
>>>> Equivalent to the PrePi based platforms, this patch implements the
>>>> newly introduced ArmVirtMemInfo library class via a separate PEIM
>>>> and PPI.
>>>>
>>>> The reason is that ArmVirtPlatformLib has populated the ArmPlatformLib
>>>> API function ArmPlatformInitializeSystemMemory () to retrieve memory
>>>> information from the DT, ensuring that it will be present when
>>>> MemoryPeim() is executed. This is a bit of a hack, and someting we
>>>> will need to get rid of if we want to reduce our dependency on
>>>> ArmPlatformLib altogether.
>>>
>>> OK, so whenever I try to look at this code, my brain crashes. This
>>> occasion is no exception. All the more reason to clean it all up; thanks
>>> for doing that.
>>>
>>> So, I guess we are talking about the following call stack. If you agree,
>>> please add it to the commit message (IMO it's OK to exceed the preferred
>>> 74 chars width for such sections):
>>>
>>>  ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf [ArmVirtPkg/ArmVirtQemu.dsc]
>>>    InitializeMemory()                            [ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.c]
>>>      ArmPlatformInitializeSystemMemory()         [ArmVirtPkg/Library/ArmVirtPlatformLib/Virt.c]
>>>        //
>>>        // set PcdSystemMemorySize from the DT
>>>        //
>>>      MemoryPeim()                                [ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.c]
>>>        InitMmu()                                 [ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.c]
>>>          ArmPlatformGetVirtualMemoryMap()        [ArmVirtPkg/Library/ArmVirtPlatformLib/VirtMem.c]
>>>            //
>>>            // consume PcdSystemMemorySize
>>>            //
>>>
>>> Here we have two ArmVirtPlatformLib actions:
>>>
>>> - The "PCD consumption" half of that has been moved -- well, copied, for
>>>  now -- to QemuVirtMemInfoLib, in patch 12/15.
>>>
>>> - And we are now looking for a new home for the "PCD production" half.
>>>
>>
>> Yes
>>
>>>> Putting this code in a ArmVirtMemInfo library constructor is
>>>> problematic as well, given that the implementation uses other
>>>> libraries, among which PcdLib, and so we need to find another way to
>>>> run it before MemoryPeim()
>>>
>>> Hm, this claim could be true :) , but I'm not totally convinced by the
>>> way you put it.
>>>
>>> First off, I notice that
>>> "ArmVirtPkg/Library/ArmVirtPlatformLib/ArmVirtPlatformLib.inf" does not
>>> spell out PcdLib as a dependency. This is quite bad, because it uses
>>> PCDs.
>>>
>>> However, ultimately, "gEfiPeiPcdPpiGuid" does end up in the final DEPEX
>>> of "MemoryInitPeim.inf", according to the ArmVirtQemu build report file.
>>> This must be due to some of the library instances already pulling in
>>> PeiPcdLib.
>>>
>>> Therefore, if we modify the constructor of QemuVirtMemInfoLib to parse
>>> the DT and to set the PCD, *plus* we spell out PcdLib in the
>>> QemuVirtMemInfoLib INF file, then the ultimate DEPEX for the
>>> MemoryInitPeim module should remain the same. And, the PeiPcdLib
>>> constructor should run before the QemuVirtMemInfoLib constructor
>>> (parsing the DT and setting the PCD).
>>>
>>> What's wrong with this argument?
>>>
>>
>> I guess you’re right. Direct dependencies between libraries with constructors are handled correctly by the tools, I simply managed to confuse myself due to the issues with transitive dependencies which you surely remember.
>
> Right, I suspected that this experience was in the background. If I
> remember correctly, the issue was when some libraries had constructors
> while some others had none (and required explicit init function calls
> instead). In some cases this mixing was not possible to avoid due to
> circular dependencies between constructors, but in turn the explicit
> calls didn't get ordered right, or some such. *shudder* :)
>

The core of the issue is that transitive library dependencies are not
honoured in the ordering of constructor invocations if they pass
through a library that has no constructor itself.

I.e., libA with a constructor

depending on libB with no constructor

depending on libC with a constructor

Currently, libA's constructor may be called before libC's constructor,
which is clearly a bug, and which is the reason why I /think/ we
generally shouldn't be relying on other libraries in constructor
implementations.

>>
>>>> So instead, create a separate PEIM that encapsulates the
>>>> ArmVirtMemInfo code and exposes it via a PPI. Another ArmVirtMemInfo
>>>> library class implementation is also provided that depexes on the PPI,
>>>> which ensures that the code is called in the correct order.
>>>
>>> I understand what this does, but I find it very complex.
>>>
>>> Sometimes, whenever we want to make sure that a PCD is set dynamically
>>> "no later than" it's consumed by a "common" module outside of
>>> ArmVirtPkg, we create a dedicated library instance (with all the right
>>> library dependencies spelled out in its INF file), set the PCD in its
>>> constructor, and hook it into the consumer module via NULL class
>>> resolution.
>>>
>>> In this case, we have a lib instance that is used through an actual lib
>>> class already, so I would suggest to add a constructor function, and to
>>> spell out the PcdLib dependency in the INF file.
>>>
>>> ... In fact, this is something that I missed in patch 12 --
>>> QemuVirtMemInfoLib already uses PCDs, but doesn't include "PcdLib" under
>>> [LibraryClasses]. That is a bug inherited from ArmVirtPlatformLib (see
>>> above), and should be fixed. And then we should only need the
>>> constructor.
>>>
>>> What do you think?
>>>
>>
>> I think you’re right.
>>
>> So how do you propose i go about creating two versions of QemuVirtMemInfoLib, only one of which has a constructor? Share the .c file between two infs in the same directory?
>
> Hm, I think I missed the impact on ArmVirtQemuKernel. In the current
> set, its DSC file is only modified in patch 12. (I missed that too.) Are
> any changes necessary for ArmVirtQemuKernel that are not contained in
> this set?
>
> Either way, what you propose above seems to be the standard approach to
> me: use two INF files, keep the bulk of the code in one (shared) C file,
> and add the constructor to another (non-shared) C file (i.e., referenced
> by only one of the INF files). Should the constructor need shared
> utility functions from the shared C file, add an internal header for those.
>

Would you object to having a single .c file, but only declare the
constructor in one of the two .INFs? The code will be pruned anyway,
due to our use of -ffunction-sections


  reply	other threads:[~2017-11-21 20:28 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-17 16:08 [PATCH 00/15] ArmVirtPkg: get rid of ArmPlatformLib Ard Biesheuvel
2017-11-17 16:08 ` [PATCH 01/15] ArmPlatformPkg/ArmPlatformLibNull: remove bogus PCD dependencies Ard Biesheuvel
2017-11-17 16:20   ` Leif Lindholm
2017-11-17 16:23     ` Ard Biesheuvel
2017-11-17 16:28       ` Leif Lindholm
2017-11-17 19:10         ` Ard Biesheuvel
2017-11-17 16:09 ` [PATCH 02/15] ArmVirtPkg/PrePi: run all library constructors by hand Ard Biesheuvel
2017-11-21 15:32   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 03/15] ArmVirtPkg/PrePi: remove unused GetPlatformPpi() function Ard Biesheuvel
2017-11-21 15:36   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 04/15] ArmVirtPkg/PrePi: remove bogus primary core check Ard Biesheuvel
2017-11-21 15:40   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 05/15] ArmVirtPkg/PrePi: remove dependency on ArmPlatformLib Ard Biesheuvel
2017-11-21 15:46   ` Laszlo Ersek
2017-11-21 15:47     ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 06/15] ArmVirtPkg/PrePi: move DRAM discovery code into PrePi Ard Biesheuvel
2017-11-21 15:48   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 07/15] ArmVirtPkg/PrePi: remove ArmPlatformStackLib dependency Ard Biesheuvel
2017-11-21 15:51   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 08/15] ArmVirtPkg/PrePi: remove bogus IntelFrameworkModulePkg.dec dependency Ard Biesheuvel
2017-11-21 15:52   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 09/15] ArmVirtPkg/ArmVirtPlatformLib: remove support for uncached mappings Ard Biesheuvel
2017-11-21 16:15   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 10/15] ArmVirtPkg: introduce ArmVirtMemInfoLib library class Ard Biesheuvel
2017-11-21 16:23   ` Laszlo Ersek
2017-11-21 16:27     ` Laszlo Ersek
2017-11-21 16:32       ` Ard Biesheuvel
2017-11-17 16:09 ` [PATCH 11/15] ArmVirtPkg/ArmVirtXen: add ArmVirtMemInfoLib implementation Ard Biesheuvel
2017-11-21 16:30   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 12/15] ArmVirtPkg/ArmVirtQemu: " Ard Biesheuvel
2017-11-21 16:47   ` Ard Biesheuvel
2017-11-21 16:56   ` Laszlo Ersek
2017-11-21 17:11     ` Ard Biesheuvel
2017-11-17 16:09 ` [PATCH 13/15] ArmVirtPkg: implement ArmVirtMemInfo PPI, PEIM and library Ard Biesheuvel
2017-11-21 17:49   ` Laszlo Ersek
2017-11-21 17:57     ` Ard Biesheuvel
2017-11-21 20:17       ` Laszlo Ersek
2017-11-21 20:32         ` Ard Biesheuvel [this message]
2017-11-22  8:45           ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 14/15] ArmVirtPkg/ArmVirtMemoryInitPeiLib: move to ArmVirtMemInfoLib Ard Biesheuvel
2017-11-21 17:51   ` Laszlo Ersek
2017-11-17 16:09 ` [PATCH 15/15] ArmVirtPkg: remove ArmPlatformLib implementations Ard Biesheuvel
2017-11-21 17:52   ` Laszlo Ersek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAKv+Gu_mRmrVh+2TiiWWqZ_OOVj-KzaqqdnLzPeanWorRvBb7Q@mail.gmail.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox