Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

PM: hibernate: move finding the resume device out of software_resume

software_resume can be called either from an init call in the boot code,
or from sysfs once the system has finished booting, and the two
invocation methods this can't race with each other.

For the latter case we did just parse the suspend device manually, while
the former might not have one. Split software_resume so that the search
only happens for the boot case, which also means the special lockdep
nesting annotation can go away as the system transition mutex can be
taken a little later and doesn't have the sysfs locking nest inside it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Rafael J. Wysocki <rafael@kernel.org>
Link: https://lore.kernel.org/r/20230531125535.676098-5-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
cc89c63e d6545e68

+39 -41
+39 -41
kernel/power/hibernate.c
··· 907 907 } 908 908 EXPORT_SYMBOL_GPL(hibernate_quiet_exec); 909 909 910 - static int find_resume_device(void) 910 + static int __init find_resume_device(void) 911 911 { 912 912 if (!strlen(resume_file)) 913 913 return -ENOENT; ··· 942 942 return 0; 943 943 } 944 944 945 - /** 946 - * software_resume - Resume from a saved hibernation image. 947 - * 948 - * This routine is called as a late initcall, when all devices have been 949 - * discovered and initialized already. 950 - * 951 - * The image reading code is called to see if there is a hibernation image 952 - * available for reading. If that is the case, devices are quiesced and the 953 - * contents of memory is restored from the saved image. 954 - * 955 - * If this is successful, control reappears in the restored target kernel in 956 - * hibernation_snapshot() which returns to hibernate(). Otherwise, the routine 957 - * attempts to recover gracefully and make the kernel return to the normal mode 958 - * of operation. 959 - */ 960 945 static int software_resume(void) 961 946 { 962 947 int error; 963 - 964 - /* 965 - * If the user said "noresume".. bail out early. 966 - */ 967 - if (noresume || !hibernation_available()) 968 - return 0; 969 - 970 - /* 971 - * name_to_dev_t() below takes a sysfs buffer mutex when sysfs 972 - * is configured into the kernel. Since the regular hibernate 973 - * trigger path is via sysfs which takes a buffer mutex before 974 - * calling hibernate functions (which take system_transition_mutex) 975 - * this can cause lockdep to complain about a possible ABBA deadlock 976 - * which cannot happen since we're in the boot code here and 977 - * sysfs can't be invoked yet. Therefore, we use a subclass 978 - * here to avoid lockdep complaining. 979 - */ 980 - mutex_lock_nested(&system_transition_mutex, SINGLE_DEPTH_NESTING); 981 - 982 - if (!swsusp_resume_device) { 983 - error = find_resume_device(); 984 - if (error) 985 - goto Unlock; 986 - } 987 948 988 949 pm_pr_dbg("Hibernation image partition %d:%d present\n", 989 950 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device)); 990 951 991 952 pm_pr_dbg("Looking for hibernation image.\n"); 953 + 954 + mutex_lock(&system_transition_mutex); 992 955 error = swsusp_check(false); 993 956 if (error) 994 957 goto Unlock; ··· 998 1035 goto Finish; 999 1036 } 1000 1037 1001 - late_initcall_sync(software_resume); 1038 + /** 1039 + * software_resume_initcall - Resume from a saved hibernation image. 1040 + * 1041 + * This routine is called as a late initcall, when all devices have been 1042 + * discovered and initialized already. 1043 + * 1044 + * The image reading code is called to see if there is a hibernation image 1045 + * available for reading. If that is the case, devices are quiesced and the 1046 + * contents of memory is restored from the saved image. 1047 + * 1048 + * If this is successful, control reappears in the restored target kernel in 1049 + * hibernation_snapshot() which returns to hibernate(). Otherwise, the routine 1050 + * attempts to recover gracefully and make the kernel return to the normal mode 1051 + * of operation. 1052 + */ 1053 + static int __init software_resume_initcall(void) 1054 + { 1055 + /* 1056 + * If the user said "noresume".. bail out early. 1057 + */ 1058 + if (noresume || !hibernation_available()) 1059 + return 0; 1060 + 1061 + if (!swsusp_resume_device) { 1062 + int error = find_resume_device(); 1063 + 1064 + if (error) 1065 + return error; 1066 + } 1067 + 1068 + return software_resume(); 1069 + } 1070 + late_initcall_sync(software_resume_initcall); 1002 1071 1003 1072 1004 1073 static const char * const hibernation_modes[] = { ··· 1170 1175 int len = n; 1171 1176 char *name; 1172 1177 dev_t res; 1178 + 1179 + if (!hibernation_available()) 1180 + return 0; 1173 1181 1174 1182 if (len && buf[len-1] == '\n') 1175 1183 len--;