Skip to content

Commit 06e8ccd

Browse files
davejiangRoss Zwisler
authored andcommitted
acpi: nfit: Add support for detect platform CPU cache flush on power loss
In ACPI 6.2a the platform capability structure has been added to the NFIT tables. That provides software the ability to determine whether a system supports the auto flushing of CPU caches on power loss. If the capability is supported, we do not need to do dax_flush(). Plumbing the path to set the property on per region from the NFIT tables. This patch depends on the ACPI NFIT 6.2a platform capabilities support code in include/acpi/actbl1.h. Signed-off-by: Dave Jiang <[email protected]> Reviewed-by: Ross Zwisler <[email protected]> Signed-off-by: Ross Zwisler <[email protected]>
1 parent a7f2766 commit 06e8ccd

File tree

4 files changed

+29
-1
lines changed

4 files changed

+29
-1
lines changed

drivers/acpi/nfit/core.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,18 @@ static bool add_flush(struct acpi_nfit_desc *acpi_desc,
838838
return true;
839839
}
840840

841+
static bool add_platform_cap(struct acpi_nfit_desc *acpi_desc,
842+
struct acpi_nfit_capabilities *pcap)
843+
{
844+
struct device *dev = acpi_desc->dev;
845+
u32 mask;
846+
847+
mask = (1 << (pcap->highest_capability + 1)) - 1;
848+
acpi_desc->platform_cap = pcap->capabilities & mask;
849+
dev_dbg(dev, "%s: cap: %#x\n", __func__, acpi_desc->platform_cap);
850+
return true;
851+
}
852+
841853
static void *add_table(struct acpi_nfit_desc *acpi_desc,
842854
struct nfit_table_prev *prev, void *table, const void *end)
843855
{
@@ -883,6 +895,10 @@ static void *add_table(struct acpi_nfit_desc *acpi_desc,
883895
case ACPI_NFIT_TYPE_SMBIOS:
884896
dev_dbg(dev, "%s: smbios\n", __func__);
885897
break;
898+
case ACPI_NFIT_TYPE_CAPABILITIES:
899+
if (!add_platform_cap(acpi_desc, table))
900+
return err;
901+
break;
886902
default:
887903
dev_err(dev, "unknown table '%d' parsing nfit\n", hdr->type);
888904
break;
@@ -2656,6 +2672,9 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
26562672
else
26572673
ndr_desc->numa_node = NUMA_NO_NODE;
26582674

2675+
if(acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_CACHE_FLUSH)
2676+
set_bit(ND_REGION_PERSIST_CACHE, &ndr_desc->flags);
2677+
26592678
list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
26602679
struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
26612680
struct nd_mapping_desc *mapping;
@@ -3464,6 +3483,7 @@ static __init int nfit_init(void)
34643483
BUILD_BUG_ON(sizeof(struct acpi_nfit_smbios) != 9);
34653484
BUILD_BUG_ON(sizeof(struct acpi_nfit_control_region) != 80);
34663485
BUILD_BUG_ON(sizeof(struct acpi_nfit_data_region) != 40);
3486+
BUILD_BUG_ON(sizeof(struct acpi_nfit_capabilities) != 16);
34673487

34683488
guid_parse(UUID_VOLATILE_MEMORY, &nfit_uuid[NFIT_SPA_VOLATILE]);
34693489
guid_parse(UUID_PERSISTENT_MEMORY, &nfit_uuid[NFIT_SPA_PM]);

drivers/acpi/nfit/nfit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ struct acpi_nfit_desc {
202202
unsigned long dimm_cmd_force_en;
203203
unsigned long bus_cmd_force_en;
204204
unsigned long bus_nfit_cmd_force_en;
205+
unsigned int platform_cap;
205206
int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
206207
void *iobuf, u64 len, int rw);
207208
};

drivers/nvdimm/pmem.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "pmem.h"
3636
#include "pfn.h"
3737
#include "nd.h"
38+
#include "nd-core.h"
3839

3940
static struct device *to_dev(struct pmem_device *pmem)
4041
{
@@ -334,7 +335,8 @@ static int pmem_attach_disk(struct device *dev,
334335
dev_warn(dev, "unable to guarantee persistence of writes\n");
335336
fua = 0;
336337
}
337-
wbc = nvdimm_has_cache(nd_region);
338+
wbc = nvdimm_has_cache(nd_region) &&
339+
!test_bit(ND_REGION_PERSIST_CACHE, &nd_region->flags);
338340

339341
if (!devm_request_mem_region(dev, res->start, resource_size(res),
340342
dev_name(&ndns->dev))) {

include/linux/libnvdimm.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ enum {
4747

4848
/* region flag indicating to direct-map persistent memory by default */
4949
ND_REGION_PAGEMAP = 0,
50+
/*
51+
* Platform ensures entire CPU store data path is flushed to pmem on
52+
* system power loss.
53+
*/
54+
ND_REGION_PERSIST_CACHE = 1,
5055

5156
/* mark newly adjusted resources as requiring a label update */
5257
DPA_RESOURCE_ADJUSTED = 1 << 0,

0 commit comments

Comments
 (0)