Eric reported that handling corresponding crash hotplug event can be failed easily when many memory hotplug event are notified in a short period. They failed because failing to take __kexec_lock. ======= [ 78.714569] Fallback order for Node 0: 0 [ 78.714575] Built 1 zonelists, mobility grouping on. Total pages: 1817886 [ 78.717133] Policy zone: Normal [ 78.724423] crash hp: kexec_trylock() failed, elfcorehdr may be inaccurate [ 78.727207] crash hp: kexec_trylock() failed, elfcorehdr may be inaccurate [ 80.056643] PEFILE: Unsigned PE binary ======= The memory hotplug events are notified very quickly and very many, while the handling of crash hotplug is much slower relatively. So the atomic variable __kexec_lock and kexec_trylock() can't guarantee the serialization of crash hotplug handling. Here, add a new mutex lock __crash_hotplug_lock to serialize crash hotplug handling specifically. This doesn't impact the usage of __kexec_lock.
Unified · Split
| @@ -739,6 +739,17 @@ subsys_initcall(crash_notes_memory_init); · 738 unmodified lines | |||
| 739 | #undef pr_fmt | 739 | #undef pr_fmt |
| 740 | #define pr_fmt(fmt) "crash hp: " fmt | 740 | #define pr_fmt(fmt) "crash hp: " fmt |
| 741 | 741 | ||
| 742 | /* | ||
| 743 | * Different than kexec/kdump loading/unloading/jumping/shrinking which | ||
| 744 | * usually rarely happen, there will be many crash hotplug events notified | ||
| 745 | * during one short period, e.g one memory board is hot added and memory | ||
| 746 | * regions are online. So mutex lock __crash_hotplug_lock is used to | ||
| 747 | * serialize the crash hotplug handling specifically. | ||
| 748 | */ | ||
| 749 | DEFINE_MUTEX(__crash_hotplug_lock); | ||
| 750 | #define crash_hotplug_lock() mutex_lock(&__crash_hotplug_lock) | ||
| 751 | #define crash_hotplug_unlock() mutex_unlock(&__crash_hotplug_lock) | ||
| 752 | |||
| 742 | /* | 753 | /* |
| 743 | * This routine utilized when the crash_hotplug sysfs node is read. | 754 | * This routine utilized when the crash_hotplug sysfs node is read. |
| 744 | * It reflects the kernel's ability/permission to update the crash | 755 | * It reflects the kernel's ability/permission to update the crash |
| @@ -748,9 +759,11 @@ int crash_check_update_elfcorehdr(void) · 3 unmodified lines | |||
| 748 | { | 759 | { |
| 749 | int rc = 0; | 760 | int rc = 0; |
| 750 | 761 | ||
| 762 | crash_hotplug_lock(); | ||
| 751 | /* Obtain lock while reading crash information */ | 763 | /* Obtain lock while reading crash information */ |
| 752 | if (!kexec_trylock()) { | 764 | if (!kexec_trylock()) { |
| 753 | pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); | 765 | pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); |
| 766 | crash_hotplug_unlock(); | ||
| 754 | return 0; | 767 | return 0; |
| 755 | } | 768 | } |
| 756 | if (kexec_crash_image) { | 769 | if (kexec_crash_image) { |
| @@ -761,6 +774,7 @@ int crash_check_update_elfcorehdr(void) · 4 unmodified lines | |||
| 761 | } | 774 | } |
| 762 | /* Release lock now that update complete */ | 775 | /* Release lock now that update complete */ |
| 763 | kexec_unlock(); | 776 | kexec_unlock(); |
| 777 | crash_hotplug_unlock(); | ||
| 764 | 778 | ||
| 765 | return rc; | 779 | return rc; |
| 766 | } | 780 | } |
| @@ -783,9 +797,11 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu) · 16 unmodified lines | |||
| 783 | { | 797 | { |
| 784 | struct kimage *image; | 798 | struct kimage *image; |
| 785 | 799 | ||
| 800 | crash_hotplug_lock(); | ||
| 786 | /* Obtain lock while changing crash information */ | 801 | /* Obtain lock while changing crash information */ |
| 787 | if (!kexec_trylock()) { | 802 | if (!kexec_trylock()) { |
| 788 | pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); | 803 | pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); |
| 804 | crash_hotplug_unlock(); | ||
| 789 | return; | 805 | return; |
| 790 | } | 806 | } |
| 791 | 807 | ||
| @@ -852,6 +868,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu) · 60 unmodified lines | |||
| 852 | out: | 868 | out: |
| 853 | /* Release lock now that update complete */ | 869 | /* Release lock now that update complete */ |
| 854 | kexec_unlock(); | 870 | kexec_unlock(); |
| 871 | crash_hotplug_unlock(); | ||
| 855 | } | 872 | } |
| 856 | 873 | ||
| 857 | static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, void *v) | 874 | static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, void *v) |