Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1733719 > unrolled thread
| Started by | Jean Delvare <jdelvare@suse.de> |
|---|---|
| First post | 2017-09-18 10:10 +0200 |
| Last post | 2017-09-25 11:30 +0200 |
| Articles | 7 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH] firmware: dmi_scan: Drop dmi_initialized Jean Delvare <jdelvare@suse.de> - 2017-09-18 10:10 +0200
Re: [PATCH] firmware: dmi_scan: Drop dmi_initialized Ingo Molnar <mingo@kernel.org> - 2017-09-23 13:00 +0200
Re: [PATCH] firmware: dmi_scan: Drop dmi_initialized Jean Delvare <jdelvare@suse.de> - 2017-09-23 17:30 +0200
Re: [PATCH] firmware: dmi_scan: Drop dmi_initialized Ingo Molnar <mingo@kernel.org> - 2017-09-24 11:20 +0200
Re: [PATCH] firmware: dmi_scan: Drop dmi_initialized Jean Delvare <jdelvare@suse.de> - 2017-09-25 11:10 +0200
Re: [PATCH] firmware: dmi_scan: Drop dmi_initialized Peter Zijlstra <peterz@infradead.org> - 2017-09-25 11:30 +0200
Re: [PATCH] firmware: dmi_scan: Drop dmi_initialized Peter Zijlstra <peterz@infradead.org> - 2017-09-25 11:30 +0200
| From | Jean Delvare <jdelvare@suse.de> |
|---|---|
| Date | 2017-09-18 10:10 +0200 |
| Subject | [PATCH] firmware: dmi_scan: Drop dmi_initialized |
| Message-ID | <uqZhT-3xJ-1@gated-at.bofh.it> |
I don't think it makes sense to check for a possible bad
initialization order at run time on every system when it is all
decided at build time.
A more efficient way to make sure developers do not introduce new
calls to dmi_check_system() too early in the initialization sequence
is to simply document the expected call order. That way, developers
have a chance to get it right immediately, without having to
test-boot their kernel, wonder why it does not work, and parse the
kernel logs for a warning message. And we get rid of the run-time
performance penalty as a nice side effect.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Cc: Ingo Molnar <mingo@kernel.org>
---
drivers/firmware/dmi_scan.c | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)
--- linux-4.14-rc0.orig/drivers/firmware/dmi_scan.c 2017-09-15 11:58:10.005977920 +0200
+++ linux-4.14-rc0/drivers/firmware/dmi_scan.c 2017-09-18 09:00:01.506399879 +0200
@@ -26,11 +26,6 @@ static u16 dmi_num;
static u8 smbios_entry_point[32];
static int smbios_entry_point_size;
-/*
- * Catch too early calls to dmi_check_system():
- */
-static int dmi_initialized;
-
/* DMI system identification string used during boot */
static char dmi_ids_string[128] __initdata;
@@ -633,7 +628,7 @@ void __init dmi_scan_machine(void)
if (!dmi_smbios3_present(buf)) {
dmi_available = 1;
- goto out;
+ return;
}
}
if (efi.smbios == EFI_INVALID_TABLE_ADDR)
@@ -651,7 +646,7 @@ void __init dmi_scan_machine(void)
if (!dmi_present(buf)) {
dmi_available = 1;
- goto out;
+ return;
}
} else if (IS_ENABLED(CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK)) {
p = dmi_early_remap(0xF0000, 0x10000);
@@ -668,7 +663,7 @@ void __init dmi_scan_machine(void)
if (!dmi_smbios3_present(buf)) {
dmi_available = 1;
dmi_early_unmap(p, 0x10000);
- goto out;
+ return;
}
memcpy(buf, buf + 16, 16);
}
@@ -686,7 +681,7 @@ void __init dmi_scan_machine(void)
if (!dmi_present(buf)) {
dmi_available = 1;
dmi_early_unmap(p, 0x10000);
- goto out;
+ return;
}
memcpy(buf, buf + 16, 16);
}
@@ -694,8 +689,6 @@ void __init dmi_scan_machine(void)
}
error:
pr_info("DMI not present or invalid.\n");
- out:
- dmi_initialized = 1;
}
static ssize_t raw_table_read(struct file *file, struct kobject *kobj,
@@ -827,14 +820,14 @@ static bool dmi_is_end_of_table(const st
* Walk the blacklist table running matching functions until someone
* returns non zero or we hit the end. Callback function is called for
* each successful match. Returns the number of matches.
+ *
+ * dmi_scan_machine must be called before this function is called.
*/
int dmi_check_system(const struct dmi_system_id *list)
{
int count = 0;
const struct dmi_system_id *d;
- WARN(!dmi_initialized, KERN_ERR "dmi check: not initialized yet.\n");
-
for (d = list; !dmi_is_end_of_table(d); d++)
if (dmi_matches(d)) {
count++;
@@ -857,6 +850,8 @@ EXPORT_SYMBOL(dmi_check_system);
*
* Walk the blacklist table until the first match is found. Return the
* pointer to the matching entry or NULL if there's no match.
+ *
+ * dmi_scan_machine must be called before this function is called.
*/
const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list)
{
--
Jean Delvare
SUSE L3 Support
[toc] | [next] | [standalone]
| From | Ingo Molnar <mingo@kernel.org> |
|---|---|
| Date | 2017-09-23 13:00 +0200 |
| Message-ID | <usQkb-22V-41@gated-at.bofh.it> |
| In reply to | #1733719 |
* Jean Delvare <jdelvare@suse.de> wrote: > I don't think it makes sense to check for a possible bad > initialization order at run time on every system when it is all > decided at build time. > > A more efficient way to make sure developers do not introduce new > calls to dmi_check_system() too early in the initialization sequence > is to simply document the expected call order. That way, developers > have a chance to get it right immediately, without having to > test-boot their kernel, wonder why it does not work, and parse the > kernel logs for a warning message. And we get rid of the run-time > performance penalty as a nice side effect. Huh? Initialization ordering requirements are very opaque, and by removing the debug check any such bugs are actively hidden. How is documentation supposed to uncover such bugs once they happen? So NAK. Thanks, Ingo
[toc] | [prev] | [next] | [standalone]
| From | Jean Delvare <jdelvare@suse.de> |
|---|---|
| Date | 2017-09-23 17:30 +0200 |
| Message-ID | <usUxr-4MR-11@gated-at.bofh.it> |
| In reply to | #1737992 |
Hi Ingo, On Sat, 23 Sep 2017 12:50:31 +0200, Ingo Molnar wrote: > * Jean Delvare <jdelvare@suse.de> wrote: > > > I don't think it makes sense to check for a possible bad > > initialization order at run time on every system when it is all > > decided at build time. > > > > A more efficient way to make sure developers do not introduce new > > calls to dmi_check_system() too early in the initialization sequence > > is to simply document the expected call order. That way, developers > > have a chance to get it right immediately, without having to > > test-boot their kernel, wonder why it does not work, and parse the > > kernel logs for a warning message. And we get rid of the run-time > > performance penalty as a nice side effect. > > Huh? Initialization ordering requirements are very opaque, They were. Now they are very documented. > and by removing the debug check any such bugs are actively hidden. How > is documentation supposed to uncover such bugs once they happen? You are looking at it the wrong way around. Documentation is how they do not happen in the first place. You hit this problem once, 9 years ago. You thought it would have been easier to debug if there was a warning, and you added it. It was one way to solve the problem but I claim it was not the best. What I expect from developers calling a function they aren't familiar with is to read its documentation first. That's the very reason why we spend time writing the documentation. They should not just call the function, boot and see if it works or not. Software engineering vs. trial and error. > So NAK. This was FYI. I maintain this subsystem, and you did not convince me. I also can't see a general trend of implementing what you suggest in the rest of the kernel. Thankfully. -- Jean Delvare SUSE L3 Support
[toc] | [prev] | [next] | [standalone]
| From | Ingo Molnar <mingo@kernel.org> |
|---|---|
| Date | 2017-09-24 11:20 +0200 |
| Message-ID | <utbeW-6SD-5@gated-at.bofh.it> |
| In reply to | #1738041 |
* Jean Delvare <jdelvare@suse.de> wrote: > Hi Ingo, > > On Sat, 23 Sep 2017 12:50:31 +0200, Ingo Molnar wrote: > > * Jean Delvare <jdelvare@suse.de> wrote: > > > > > I don't think it makes sense to check for a possible bad > > > initialization order at run time on every system when it is all > > > decided at build time. > > > > > > A more efficient way to make sure developers do not introduce new > > > calls to dmi_check_system() too early in the initialization sequence > > > is to simply document the expected call order. That way, developers > > > have a chance to get it right immediately, without having to > > > test-boot their kernel, wonder why it does not work, and parse the > > > kernel logs for a warning message. And we get rid of the run-time > > > performance penalty as a nice side effect. > > > > Huh? Initialization ordering requirements are very opaque, > > They were. Now they are very documented. > > > and by removing the debug check any such bugs are actively hidden. How > > is documentation supposed to uncover such bugs once they happen? > > You are looking at it the wrong way around. Documentation is how they > do not happen in the first place. That expectation, as a general statement, is very naive and contrary to experience: documentation is fine for one layer of defense to prevent bugs, but _when_ they happen and a bug slips through, documentation does not help anymore, because the dependencies in the _code_ are opaque and non-obvious ... For example during the early SMP efforts of Linux we used to document lock dependencies as well, but once the kernel had more than a dozen spinlocks we periodically ran into deadlocks and the whole design became unmaintainable quickly. So we have lockdep in addition to documentation. > You hit this problem once, 9 years ago. You thought it would have been easier to > debug if there was a warning, and you added it. I did not just 'think' it would have been easier to debug, I wasted time on that bug and a warning would have helped so I added it. That was and remains objectively true. While I expect most such warnings to never see any public email lists (because once a developer triggers it it gets fixed without the bug ever getting triggered by others), yet searching for "dmi check: not initialized yet" still finds a couple of incidents where real or potential bugs were found by this init dependency check, such as: http://lists.infradead.org/pipermail/linux-arm-kernel/2014-September/289347.html or this: https://www.spinics.net/lists/linux-acpi/msg28698.html ... so this warning actually helped a number of kernel developers to not waste time on the opaque dependency. This is a warning that was added due to an _actual category of bugs_, which has been triggered subsequently as well, so it's not a frivolous warning by any meaning. > [...] It was one way to solve the problem but I claim it was not the best. > > What I expect from developers calling a function they aren't familiar > with is to read its documentation first. That's the very reason why we > spend time writing the documentation. They should not just call the > function, boot and see if it works or not. Software engineering vs. > trial and error. This statement is breathtaking in its ignorance :-( > > So NAK. > > This was FYI. I maintain this subsystem, and you did not convince me. I also > can't see a general trend of implementing what you suggest in the rest of the > kernel. Thankfully. I find the arrogance displayed here breathtaking as well - the last thing we need is for firmware interfacing kernel code to become _more_ fragile. This was and continues to be a useful warning - but what worries me even more is not just the removal of the warning, but the false and technically invalid justifications under which it is removed... For those reasons I maintain my NAK: Nacked-by: Ingo Molnar <mingo@kernel.org> Thanks, Ingo
[toc] | [prev] | [next] | [standalone]
| From | Jean Delvare <jdelvare@suse.de> |
|---|---|
| Date | 2017-09-25 11:10 +0200 |
| Message-ID | <utxyN-4k5-13@gated-at.bofh.it> |
| In reply to | #1738126 |
On Sun, 24 Sep 2017 11:16:25 +0200, Ingo Molnar wrote: > * Jean Delvare <jdelvare@suse.de> wrote: > > On Sat, 23 Sep 2017 12:50:31 +0200, Ingo Molnar wrote: > > > * Jean Delvare <jdelvare@suse.de> wrote: > > > > I don't think it makes sense to check for a possible bad > > > > initialization order at run time on every system when it is all > > > > decided at build time. > > > > > > > > A more efficient way to make sure developers do not introduce new > > > > calls to dmi_check_system() too early in the initialization sequence > > > > is to simply document the expected call order. That way, developers > > > > have a chance to get it right immediately, without having to > > > > test-boot their kernel, wonder why it does not work, and parse the > > > > kernel logs for a warning message. And we get rid of the run-time > > > > performance penalty as a nice side effect. > > > > > > Huh? Initialization ordering requirements are very opaque, > > > > They were. Now they are very documented. > > > > > and by removing the debug check any such bugs are actively hidden. How > > > is documentation supposed to uncover such bugs once they happen? > > > > You are looking at it the wrong way around. Documentation is how they > > do not happen in the first place. > > That expectation, as a general statement, is very naive and contrary to > experience: documentation is fine for one layer of defense to prevent bugs, but > _when_ they happen and a bug slips through, documentation does not help anymore, > because the dependencies in the _code_ are opaque and non-obvious ... Seriously... dmi_scan_machine must be called before dmi_check_system, how is that "opaque"? Non-obvious, maybe, hence the need to document it. I can find 169 occurrences of "(must|has to|should) be called (before|after)" in the kernel source tree, plus 19 occurrences of "call this function (before|after)" so apparently I'm not the only fool who thinks documenting such ordering requirements is worthwhile. > For example during the early SMP efforts of Linux we used to document lock > dependencies as well, but once the kernel had more than a dozen spinlocks we > periodically ran into deadlocks and the whole design became unmaintainable > quickly. So we have lockdep in addition to documentation. And lockdep is good, because it helps solve a very complex problem, and is able to catch potential issues before they happen. I'm very happy that bright people designed it, and I am well aware that it caught a huge number of bugs. Also note that lockdep can be disabled, so you don't suffer the overhead at run-time if you don't want to. There is no way to disable the code you added back then. I wish I could make your check depend on some general kernel debugging option, unfortunately CONFIG_DEBUG_KERNEL covers so much that it is almost impossible to do without it and it ends up being enabled even on production kernels. Maybe we'd need a separate option for developer mode (something like CFG80211_DEVELOPER_WARNINGS but generalized to the whole kernel.) And yes, I am well aware that the performance penalty of your check was nowhere close to that of lockdep. But add a bit here and a bit there... More and more drivers are calling dmi_check_system. > > You hit this problem once, 9 years ago. You thought it would have been easier to > > debug if there was a warning, and you added it. > > [...] It was one way to solve the problem but I claim it was not the best. > > I did not just 'think' it would have been easier to debug, I wasted time on that > bug and a warning would have helped so I added it. That was and remains > objectively true. > > While I expect most such warnings to never see any public email lists (because > once a developer triggers it it gets fixed without the bug ever getting triggered > by others), yet searching for "dmi check: not initialized yet" still finds a > couple of incidents where real or potential bugs were found by this init > dependency check, such as: > > http://lists.infradead.org/pipermail/linux-arm-kernel/2014-September/289347.html Here it indeed helped spot a bug quickly. But I have little doubt the issue would have been found fast even without it, as disabling DMI support completely on half of the arm64 systems would hardly go unnoticed for long. > or this: > > https://www.spinics.net/lists/linux-acpi/msg28698.html > > ... so this warning actually helped a number of kernel developers to not > waste time on the opaque dependency. But here it was a case where it did not matter, and developers ended up silencing the warning instead of actually fixing the ordering. Without your warning, they would actually have saved time. A hack which will break as soon as my patch named "firmware: dmi: Optimize dmi_matches" [1] hits mainline, BTW. Thanks for the pointer, I'll get in touch with the involved developers to find a proper fix. [1] https://marc.info/?l=linux-kernel&m=150113709717948&w=2 > This is a warning that was added due > to an _actual category of bugs_, which has been triggered subsequently as > well, so it's not a frivolous warning by any meaning. I don't see any category here (unlike lockdep.) That's a single bug, with 2 known occurrences in 10 years. > > (...) > > This was FYI. I maintain this subsystem, and you did not convince me. I also > > can't see a general trend of implementing what you suggest in the rest of the > > kernel. Thankfully. > > I find the arrogance displayed here breathtaking as well - the last thing we need > is for firmware interfacing kernel code to become _more_ fragile. We don't need it to become slower, more bloated and less documented either. And there's a trade-off in everything. > This was and continues to be a useful warning - but what worries me even more is > not just the removal of the warning, but the false and technically invalid > justifications under which it is removed... Then we have that in common. While reading the code and its history, I was worried that the justification to add this warning in the first place was technically weak. Not every coding error must automatically translate to a patch to make the code robust against said error. Sometimes you just have to admit that you did not pay attention as you should have, fix your mistake, possibly document it for others, and move on. Otherwise we end up with slow bloated code. -- Jean Delvare SUSE L3 Support
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-09-25 11:30 +0200 |
| Message-ID | <utxSa-4rR-9@gated-at.bofh.it> |
| In reply to | #1738845 |
On Mon, Sep 25, 2017 at 11:00:11AM +0200, Jean Delvare wrote: > Then we have that in common. While reading the code and its history, I > was worried that the justification to add this warning in the first > place was technically weak. Not every coding error must automatically > translate to a patch to make the code robust against said error. > Sometimes you just have to admit that you did not pay attention as you > should have, fix your mistake, possibly document it for others, and > move on. Otherwise we end up with slow bloated code. That WARN_ON() is a form of documentation. And if you care about performance for your code path, hide it under some CONFIG_*_DEBUG, but in general WARN_ON() isn't terribly expensive (depending entirely on the complexity of the condition of course).
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-09-25 11:30 +0200 |
| Message-ID | <utxSa-4rR-11@gated-at.bofh.it> |
| In reply to | #1738845 |
On Mon, Sep 25, 2017 at 11:00:11AM +0200, Jean Delvare wrote: > I can find 169 occurrences of "(must|has to|should) be called > (before|after)" in the kernel source tree, plus 19 occurrences of "call > this function (before|after)" so apparently I'm not the only fool who > thinks documenting such ordering requirements is worthwhile. Documenting things is good, assuming people read it is another. In fact its provably incorrect, people simply don't read. I've been slowly converting all those occurrences of "should be called with 'foo' lock held" into: lockdep_assert_held(&foo); simply because people do _not_ read. And even if they did read, its still easy to forget and make a mistake. Heck, I sometimes get it wrong on code I wrote. Documentation good, runtime checks also good. Because when you do get it wrong p(someone getting it wrong at some point) = 1, a WARN_ON_ONCE() triggering that has a comment that says: /* * if you trigger this; you violated rule #123 */ WARN_ON_ONCE(!invariant_cond_123); saves ever so much more time than debugging weird and wonderful splats much later in the code that rely on our rule #123.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web