Skip to content

Commit 459d0dd

Browse files
committed
nfit, address-range-scrub: determine one platform max_ars value
acpi_nfit_query_poison() is awkward in that it requires an nfit_spa argument in order to determine what max_ars value to use. Instead probe for the minimum max_ars across all scrub-capable ranges in the system and drop the nfit_spa argument. This enables a larger rework / simplification of the ARS state machine whereby the status can be retrieved once and then iterated over all address ranges to reap completions. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 3013e17 commit 459d0dd

File tree

2 files changed

+41
-39
lines changed

2 files changed

+41
-39
lines changed

drivers/acpi/nfit/core.c

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,16 +2494,16 @@ static int ars_get_status(struct acpi_nfit_desc *acpi_desc)
24942494
int rc, cmd_rc;
24952495

24962496
rc = nd_desc->ndctl(nd_desc, NULL, ND_CMD_ARS_STATUS, ars_status,
2497-
acpi_desc->ars_status_size, &cmd_rc);
2497+
acpi_desc->max_ars, &cmd_rc);
24982498
if (rc < 0)
24992499
return rc;
25002500
return cmd_rc;
25012501
}
25022502

2503-
static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc,
2504-
struct nd_cmd_ars_status *ars_status)
2503+
static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc)
25052504
{
25062505
struct nvdimm_bus *nvdimm_bus = acpi_desc->nvdimm_bus;
2506+
struct nd_cmd_ars_status *ars_status = acpi_desc->ars_status;
25072507
int rc;
25082508
u32 i;
25092509

@@ -2739,60 +2739,35 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
27392739
return rc;
27402740
}
27412741

2742-
static int ars_status_alloc(struct acpi_nfit_desc *acpi_desc,
2743-
u32 max_ars)
2742+
static int ars_status_alloc(struct acpi_nfit_desc *acpi_desc)
27442743
{
27452744
struct device *dev = acpi_desc->dev;
27462745
struct nd_cmd_ars_status *ars_status;
27472746

2748-
if (acpi_desc->ars_status && acpi_desc->ars_status_size >= max_ars) {
2749-
memset(acpi_desc->ars_status, 0, acpi_desc->ars_status_size);
2747+
if (acpi_desc->ars_status) {
2748+
memset(acpi_desc->ars_status, 0, acpi_desc->max_ars);
27502749
return 0;
27512750
}
27522751

2753-
if (acpi_desc->ars_status)
2754-
devm_kfree(dev, acpi_desc->ars_status);
2755-
acpi_desc->ars_status = NULL;
2756-
ars_status = devm_kzalloc(dev, max_ars, GFP_KERNEL);
2752+
ars_status = devm_kzalloc(dev, acpi_desc->max_ars, GFP_KERNEL);
27572753
if (!ars_status)
27582754
return -ENOMEM;
27592755
acpi_desc->ars_status = ars_status;
2760-
acpi_desc->ars_status_size = max_ars;
27612756
return 0;
27622757
}
27632758

2764-
static int acpi_nfit_query_poison(struct acpi_nfit_desc *acpi_desc,
2765-
struct nfit_spa *nfit_spa)
2759+
static int acpi_nfit_query_poison(struct acpi_nfit_desc *acpi_desc)
27662760
{
2767-
struct acpi_nfit_system_address *spa = nfit_spa->spa;
27682761
int rc;
27692762

2770-
if (!nfit_spa->max_ars) {
2771-
struct nd_cmd_ars_cap ars_cap;
2772-
2773-
memset(&ars_cap, 0, sizeof(ars_cap));
2774-
rc = ars_get_cap(acpi_desc, &ars_cap, nfit_spa);
2775-
if (rc < 0)
2776-
return rc;
2777-
nfit_spa->max_ars = ars_cap.max_ars_out;
2778-
nfit_spa->clear_err_unit = ars_cap.clear_err_unit;
2779-
/* check that the supported scrub types match the spa type */
2780-
if (nfit_spa_type(spa) == NFIT_SPA_VOLATILE &&
2781-
((ars_cap.status >> 16) & ND_ARS_VOLATILE) == 0)
2782-
return -ENOTTY;
2783-
else if (nfit_spa_type(spa) == NFIT_SPA_PM &&
2784-
((ars_cap.status >> 16) & ND_ARS_PERSISTENT) == 0)
2785-
return -ENOTTY;
2786-
}
2787-
2788-
if (ars_status_alloc(acpi_desc, nfit_spa->max_ars))
2763+
if (ars_status_alloc(acpi_desc))
27892764
return -ENOMEM;
27902765

27912766
rc = ars_get_status(acpi_desc);
27922767
if (rc < 0 && rc != -ENOSPC)
27932768
return rc;
27942769

2795-
if (ars_status_process_records(acpi_desc, acpi_desc->ars_status))
2770+
if (ars_status_process_records(acpi_desc))
27962771
return -ENOMEM;
27972772

27982773
return 0;
@@ -2824,7 +2799,7 @@ static void acpi_nfit_async_scrub(struct acpi_nfit_desc *acpi_desc,
28242799

28252800
if (acpi_desc->cancel)
28262801
break;
2827-
rc = acpi_nfit_query_poison(acpi_desc, nfit_spa);
2802+
rc = acpi_nfit_query_poison(acpi_desc);
28282803
if (rc == -ENOTTY)
28292804
break;
28302805
if (rc == -EBUSY && !tmo) {
@@ -2925,7 +2900,7 @@ static void acpi_nfit_scrub(struct work_struct *work)
29252900
*/
29262901
rc = 0;
29272902
} else
2928-
rc = acpi_nfit_query_poison(acpi_desc, nfit_spa);
2903+
rc = acpi_nfit_query_poison(acpi_desc);
29292904

29302905
if (rc == -ENOTTY) {
29312906
/* no ars capability, just register spa and move on */
@@ -3018,6 +2993,31 @@ static void acpi_nfit_scrub(struct work_struct *work)
30182993
mutex_unlock(&acpi_desc->init_mutex);
30192994
}
30202995

2996+
static void acpi_nfit_init_ars(struct acpi_nfit_desc *acpi_desc,
2997+
struct nfit_spa *nfit_spa)
2998+
{
2999+
int type = nfit_spa_type(nfit_spa->spa);
3000+
struct nd_cmd_ars_cap ars_cap;
3001+
int rc;
3002+
3003+
memset(&ars_cap, 0, sizeof(ars_cap));
3004+
rc = ars_get_cap(acpi_desc, &ars_cap, nfit_spa);
3005+
if (rc < 0)
3006+
return;
3007+
/* check that the supported scrub types match the spa type */
3008+
if (type == NFIT_SPA_VOLATILE && ((ars_cap.status >> 16)
3009+
& ND_ARS_VOLATILE) == 0)
3010+
return;
3011+
if (type == NFIT_SPA_PM && ((ars_cap.status >> 16)
3012+
& ND_ARS_PERSISTENT) == 0)
3013+
return;
3014+
3015+
nfit_spa->max_ars = ars_cap.max_ars_out;
3016+
nfit_spa->clear_err_unit = ars_cap.clear_err_unit;
3017+
acpi_desc->max_ars = max(nfit_spa->max_ars, acpi_desc->max_ars);
3018+
}
3019+
3020+
30213021
static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
30223022
{
30233023
struct nfit_spa *nfit_spa;
@@ -3026,8 +3026,10 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
30263026
int rc, type = nfit_spa_type(nfit_spa->spa);
30273027

30283028
/* PMEM and VMEM will be registered by the ARS workqueue */
3029-
if (type == NFIT_SPA_PM || type == NFIT_SPA_VOLATILE)
3029+
if (type == NFIT_SPA_PM || type == NFIT_SPA_VOLATILE) {
3030+
acpi_nfit_init_ars(acpi_desc, nfit_spa);
30303031
continue;
3032+
}
30313033
/* BLK apertures belong to BLK region registration below */
30323034
if (type == NFIT_SPA_BDW)
30333035
continue;

drivers/acpi/nfit/nfit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,10 @@ struct acpi_nfit_desc {
197197
struct device *dev;
198198
u8 ars_start_flags;
199199
struct nd_cmd_ars_status *ars_status;
200-
size_t ars_status_size;
201200
struct work_struct work;
202201
struct list_head list;
203202
struct kernfs_node *scrub_count_state;
203+
unsigned int max_ars;
204204
unsigned int scrub_count;
205205
unsigned int scrub_mode;
206206
unsigned int cancel:1;

0 commit comments

Comments
 (0)