History

PM, libnvdimm: Add runtime firmware activation support

Abstract platform specific mechanics for nvdimm firmware activation behind a handful of generic ops. At the bus level ->activate_state() indicates the unified state (idle, busy, armed) of all DIMMs on the bus, and ->capability() indicates the system state expectations for activate. At the DIMM level ->activate_state() indicates the per-DIMM state, ->activate_result() indicates the outcome of the last activation attempt, and ->arm() attempts to transition the DIMM from 'idle' to 'armed'. A new hibernate_quiet_exec() facility is added to support firmware activation in an OS defined system quiesce state. It leverages the fact that the hibernate-freeze state wants to assert that a memory hibernation snapshot can be taken. This is in contrast to a platform firmware defined quiesce state that may forcefully quiet the memory controller independent of whether an individual device-driver properly supports hibernate-freeze. The libnvdimm sysfs interface is extended to support detection of a firmware activate capability. The mechanism supports enumeration and triggering of firmware activate, optionally in the hibernate_quiet_exec() context. [rafael: hibernate_quiet_exec() proposal] [vishal: fix up sparse warning, grammar in Documentation/]

Dan Williams committed 6 years ago

Commit 48001ea1 parent 5cf81ce8 files · +500 −0Browse files

Showing the changes to include/linux (2 of 8 files). Show all

Unified · Split

2 files
  1. include/linux/libnvdimm.h +44 −0
  2. include/linux/suspend.h +6 −0
include/linux/libnvdimm.h+44−0
@@ -86,6 +86,7 @@ struct nvdimm_bus_descriptor { · 85 unmodified lines
86 int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc);86 int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc);
87 int (*clear_to_send)(struct nvdimm_bus_descriptor *nd_desc,87 int (*clear_to_send)(struct nvdimm_bus_descriptor *nd_desc,
88 struct nvdimm *nvdimm, unsigned int cmd, void *data);88 struct nvdimm *nvdimm, unsigned int cmd, void *data);
89 const struct nvdimm_bus_fw_ops *fw_ops;
89};90};
90 91
91struct nd_cmd_desc {92struct nd_cmd_desc {
@@ -200,6 +201,49 @@ struct nvdimm_security_ops { · 108 unmodified lines
200 int (*query_overwrite)(struct nvdimm *nvdimm);201 int (*query_overwrite)(struct nvdimm *nvdimm);
201};202};
202 203
204enum nvdimm_fwa_state {
205 NVDIMM_FWA_INVALID,
206 NVDIMM_FWA_IDLE,
207 NVDIMM_FWA_ARMED,
208 NVDIMM_FWA_BUSY,
209 NVDIMM_FWA_ARM_OVERFLOW,
210};
211
212enum nvdimm_fwa_trigger {
213 NVDIMM_FWA_ARM,
214 NVDIMM_FWA_DISARM,
215};
216
217enum nvdimm_fwa_capability {
218 NVDIMM_FWA_CAP_INVALID,
219 NVDIMM_FWA_CAP_NONE,
220 NVDIMM_FWA_CAP_QUIESCE,
221 NVDIMM_FWA_CAP_LIVE,
222};
223
224enum nvdimm_fwa_result {
225 NVDIMM_FWA_RESULT_INVALID,
226 NVDIMM_FWA_RESULT_NONE,
227 NVDIMM_FWA_RESULT_SUCCESS,
228 NVDIMM_FWA_RESULT_NOTSTAGED,
229 NVDIMM_FWA_RESULT_NEEDRESET,
230 NVDIMM_FWA_RESULT_FAIL,
231};
232
233struct nvdimm_bus_fw_ops {
234 enum nvdimm_fwa_state (*activate_state)
235 (struct nvdimm_bus_descriptor *nd_desc);
236 enum nvdimm_fwa_capability (*capability)
237 (struct nvdimm_bus_descriptor *nd_desc);
238 int (*activate)(struct nvdimm_bus_descriptor *nd_desc);
239};
240
241struct nvdimm_fw_ops {
242 enum nvdimm_fwa_state (*activate_state)(struct nvdimm *nvdimm);
243 enum nvdimm_fwa_result (*activate_result)(struct nvdimm *nvdimm);
244 int (*arm)(struct nvdimm *nvdimm, enum nvdimm_fwa_trigger arg);
245};
246
203void badrange_init(struct badrange *badrange);247void badrange_init(struct badrange *badrange);
204int badrange_add(struct badrange *badrange, u64 addr, u64 length);248int badrange_add(struct badrange *badrange, u64 addr, u64 length);
205void badrange_forget(struct badrange *badrange, phys_addr_t start,249void badrange_forget(struct badrange *badrange, phys_addr_t start,
include/linux/suspend.h+6−0
@@ -453,6 +453,8 @@ extern bool hibernation_available(void); · 452 unmodified lines
453asmlinkage int swsusp_save(void);453asmlinkage int swsusp_save(void);
454extern struct pbe *restore_pblist;454extern struct pbe *restore_pblist;
455int pfn_is_nosave(unsigned long pfn);455int pfn_is_nosave(unsigned long pfn);
456
457int hibernate_quiet_exec(int (*func)(void *data), void *data);
456#else /* CONFIG_HIBERNATION */458#else /* CONFIG_HIBERNATION */
457static inline void register_nosave_region(unsigned long b, unsigned long e) {}459static inline void register_nosave_region(unsigned long b, unsigned long e) {}
458static inline void register_nosave_region_late(unsigned long b, unsigned long e) {}460static inline void register_nosave_region_late(unsigned long b, unsigned long e) {}
@@ -464,6 +466,10 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op · 5 unmodified lines
464static inline int hibernate(void) { return -ENOSYS; }466static inline int hibernate(void) { return -ENOSYS; }
465static inline bool system_entering_hibernation(void) { return false; }467static inline bool system_entering_hibernation(void) { return false; }
466static inline bool hibernation_available(void) { return false; }468static inline bool hibernation_available(void) { return false; }
469
470static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) {
471 return -ENOTSUPP;
472}
467#endif /* CONFIG_HIBERNATION */473#endif /* CONFIG_HIBERNATION */
468 474
469#ifdef CONFIG_HIBERNATION_SNAPSHOT_DEV475#ifdef CONFIG_HIBERNATION_SNAPSHOT_DEV

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t