Hi Peter, Thank you for review. On 02/19/2016 01:03 AM, Peter Hurley wrote: > On 02/17/2016 07:36 PM, Zheng, Lv wrote: >> Hi, >> >>> From: Aleksey Makarov [mailto:aleksey.makarov@xxxxxxxxxx] >>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for >>> early_acpi_os_unmap_memory() >>> >>> Hi Lv, >>> >>> Thank you for review. >>> >>> On 02/17/2016 05:51 AM, Zheng, Lv wrote: >>> >>> [..] >>> >>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls >>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not >>> set. >>>>>> >>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init() >>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere >>>>>> >>>>>> We need this function to be non-__init because we need access to >>>>>> some tables at unpredictable time--it may be before or after >>>>>> acpi_gbl_permanent_mmap is set. For example, SPCR (Serial Port Console >>>>>> Redirection) table is needed each time a new console is registered. >>>>>> It can be quite early (console_initcall) or when a module is inserted. >>>>>> When this table accessed before acpi_gbl_permanent_mmap is set, >>>>>> the pointer should be unmapped. This is exactly what this function >>>>>> does. >>>>> [Lv Zheng] >>>>> Why don't you use another API instead of early_acpi_os_unmap_memory() >>> in >>>>> case you want to unmap things in any cases. >>>>> acpi_os_unmap_memory() should be the one to match this purpose. >>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem(). >>> >>> As far as I understand, there exist two steps in ACPI initialization: >>> >>> 1. Before acpi_gbl_permanent_mmap is set, tables received with >>> acpi_get_table_with_size() >>> are mapped by early_memremap(). If a subsystem gets such a pointer it >>> should be unmapped. >>> >>> 2 After acpi_gbl_permanent_mmap is set this pointer should not be unmapped >>> at all. >>> >> [Lv Zheng] >> This statement is wrong, this should be: >> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped. >> In fact, we have a series to introduce acpi_put_table() to achieve this. >> So your argument is wrong from very first point. >> >>> That exactly what early_acpi_os_unmap_memory() does--it checks >>> acpi_gbl_permanent_mmap. >>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had >>> been set, >>> it would have tried to free that pointer with an oops (actually, I checked that >>> and got that oops). >>> >>> So using acpi_os_unmap_memory() is not an option here, but >>> early_acpi_os_unmap_memory() >>> match perfectly. >> [Lv Zheng] >> I don't think so. >> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter. >> But for the data tables, OSPMs should use them in this way: >> 1. map the table >> 2. parse the table and convert it to OS specific structures >> 3. unmap the table >> This helps to shrink virtual memory address space usages. >> >> So from this point of view, all data tables should be unmapped right after being parsed. >> Why do you need the map to be persistent in the kernel address space? >> You can always map a small table, but what if the table size is very big? >> >>> >>>>> And in fact early_acpi_os_unmap_memory() should be removed. >>> >>> I don't think so -- I have explained why. It does different thing. >>> Probably it (and/or other functions in that api) should be renamed. >>> >> [Lv Zheng] >> Just let me ask one more question. >> eary_acpi_os_unmap_memory() is not used inside of ACPICA. >> How ACPICA can work with just acpi_os_unmap_memory()? >> You can check drivers/acpi/tbxxx.c. >> Especially: acpi_tb_release_temp_table() and the code invoking it. >> >>>> [Lv Zheng] >>>> One more thing is: >>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of >>> early_acpi_os_unmap_memory(), >>>> then it implies that your driver does have a defect. >>> >>> I still don't understand what defect, sorry. >> [Lv Zheng] >> If you can't ensure this sequence for using the data tables: >> 1. map the table >> 2. parse the table and convert it to OS specific structure >> 3. unmap the table >> It implies there is a bug in the driver or a bug in the ACPI subsystem core. > > Exactly. > > The central problem here is the way Aleksey is trying to hookup a console. > > What should be happening in this series is: > 1. early map SPCR > 2. parse the SPCR table > 3. call add_preferred_console() to add the SPCR console to the console table > 4. unmap SPCR This does not work. SPCR specifies address of the console, but add_preferred_console() accepts name of console and its index. There are no general method to translate address to name at such an early stage. There is another reason why I prefer to parse SPCR each time a console is registered. Some consoles can be registered very early in the initialization process and we have to be sure add_preferred_console() is called before that. Of course, I could just parse it once and cache the results, but this still requires accessing SPCR before acpi_gbl_permanent_mmap is set *or* after that. > This trivial and unobtrusive method would already have a 8250 console > running via SPCR. I've already pointed this out in previous reviews. > > Further, the above method *will be required anyway* for the DBG2 table to > start an earlycon, which I've already pointed out in previous reviews. > > Then to enable amba-pl011 console via ACPI, add a console match() method > similar to the 8250 console match() method, univ8250_console_match(). So are you suggesting a separate method for each possible console? This is not acceptable. Do you suggest making up separate new name (like "uart" for 8250) for each type of conosole SPCR can specify? > FWIW, PCI earlycon + console support was already submitted once before but > never picked up by GregKH. I think I'll just grab that and re-submit so > you would know what to emit for console options in the add_preferred_console(). Please do. Or just send a link to to that submission. Do you mean the Leif Lindholm's patches: https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm@xxxxxxxxxx He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device (I just match SPCR against data that struct uart_port already has) 2) As you are suggesting, he parses SPCR once at a predefined point in initialization. And that's why his submission is RFC: he had troubles with the order of initialization. Thank you Aleksey Makarov > Regards, > Peter Hurley > > >>>> There is an early bootup requirement in Linux. >>>> Maps acquired during the early stage should be freed by the driver during the >>> early stage. >>>> And the driver should re-acquire the memory map after booting. >>> >>> Exactly. That's why I use early_acpi_os_unmap_memory(). The point is that >>> that code can be >>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for >>> example 8250 console) >>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that >>> registers a console), >>> We just can not tell if the received table pointer should or sould not be freed >>> with early_memunmap() >>> (actually __acpi_unmap_table() or whatever) without checking >>> acpi_gbl_permanent_mmap, >>> but that's all too low level. >> [Lv Zheng] >> The driver should make sure that: >> Map/unmap is paired during early stage. >> For late stage, it should be another pair of map/unmap. >> >>> >>> Another option, as you describe, is to get this pointer early, don't free it >> [Lv Zheng] >> I mean you should free it early. >> >>> untill acpi_gbl_permanent_mmap is set, then free it (with >>> early_acpi_os_unmap_memory(), that's >>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the >>> persistent >>> pointer to the table. The problem with it is that we can not just watch >>> acpi_gbl_permanent_mmap >>> to catch this exact moment. And also accessing acpi_gbl_permanent_mmap is >>> not good as it probably is >>> an implementation detail (i. e. too lowlevel) of the ACPI code. >>> Or I probably miss what you are suggesting. >>> >> [Lv Zheng] >> I mean, you should: >> During early stage: >> acpi_os_map_memory() >> Parse the table. >> acpi_os_unmap_memory(). >> >>>> This is because, during early bootup stage, there are only limited slots >>> available for drivers to map memory. >>>> So by changing __init to __ref here, you probably will hide many such defects. >>> >>> What defects? This funcions checks acpi_gbl_permanent_mmap. >>> BTW, exactly the same thing is done in the beginning of >>> acpi_os_unmap_memory() and than's ok, >>> that function is __ref. >>> >>>> And solving issues in this way doesn't seem to be an improvement. >>> >>> Could you please tell me where I am wrong? I still don't understand your point. >> [Lv Zheng] >> But anyway, the defect should be in ACPI subsystem core. >> The cause should be the API itself - acpi_get_table(). >> >> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up. >> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked. >> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory() for now. >> >> Thanks and best regards >> -Lv >> >>> >>> Thank you >>> Aleksey Makarov >>> >>>> >>>> Thanks and best regards >>>> -Lv >>>> >>>>> >>>>> Thanks and best regards >>>>> -Lv >>>>> >>>>>> >>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@xxxxxxxxxx> >>>>>> --- >>>>>> drivers/acpi/osl.c | 6 +++++- >>>>>> 1 file changed, 5 insertions(+), 1 deletion(-) >>>>>> >>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c >>>>>> index 67da6fb..8a552cd 100644 >>>>>> --- a/drivers/acpi/osl.c >>>>>> +++ b/drivers/acpi/osl.c >>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt, >>>>>> acpi_size size) >>>>>> } >>>>>> EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); >>>>>> >>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size >>>>> size) >>>>>> +/* >>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init() >>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere >>>>>> + */ >>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size >>>>> size) >>>>>> { >>>>>> if (!acpi_gbl_permanent_mmap) >>>>>> __acpi_unmap_table(virt, size); >>>>>> -- >>>>>> 2.7.1 >>>>>> >>>>>> -- >>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in >>>>>> the body of a message to majordomo@xxxxxxxxxxxxxxx >>>>>> More majordomo info at http://vger.kernel.org/majordomo-info.html >>>>> -- >>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in >>>>> the body of a message to majordomo@xxxxxxxxxxxxxxx >>>>> More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html