From: Linda Knippers <linda.knippers@hpe.com>
To: Dan Williams <dan.j.williams@intel.com>, linux-nvdimm@lists.01.org
Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: Re: [PATCH 1/3] nfit: fix multi-interface dimm handling, acpi6.1 compatibility
Date: Mon, 8 Feb 2016 14:10:58 -0500 [thread overview]
Message-ID: <56B8E842.9080506@hpe.com> (raw)
In-Reply-To: <20160208183058.27820.87950.stgit@dwillia2-desk3.amr.corp.intel.com>
On 2/8/2016 1:30 PM, Dan Williams wrote:
> ACPI 6.1 clarified that multi-interface dimms require multiple control
> region entries (DCRs) per dimm. Previously we were assuming that a
> control region is only present when block-data-windows are present.
We need to give this a quick test with NVDIMM-N because those types of
NVDIMMs have control regions without block-data-windows. We've fixed
bugs related to that assumption a couple of times.
> This implementation was done with an eye to be compatibility with the
> looser ACPI 6.0 interpretation of this table.
>
> 1/ When coalescing the memory device (MEMDEV) tables for a single dimm,
> coalesce on device_handle rather than control region index.
>
> 2/ Whenever we disocver a control region with non-zero block windows
discover
> re-scan for block-data-window (BDW) entries.
>
> We may need to revisit this if a DIMM ever implements a format interface
> outside of blk or pmem, but that is not on the foreseeable horizon.
>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
> drivers/acpi/nfit.c | 71 +++++++++++++++++++++++++--------------------------
> 1 file changed, 35 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
> index ad6d8c6b777e..424b362e8fdc 100644
> --- a/drivers/acpi/nfit.c
> +++ b/drivers/acpi/nfit.c
> @@ -469,37 +469,16 @@ static void nfit_mem_find_spa_bdw(struct acpi_nfit_desc *acpi_desc,
> nfit_mem->bdw = NULL;
> }
>
> -static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc,
> +static void nfit_mem_init_bdw(struct acpi_nfit_desc *acpi_desc,
> struct nfit_mem *nfit_mem, struct acpi_nfit_system_address *spa)
> {
> u16 dcr = __to_nfit_memdev(nfit_mem)->region_index;
> struct nfit_memdev *nfit_memdev;
> struct nfit_flush *nfit_flush;
> - struct nfit_dcr *nfit_dcr;
> struct nfit_bdw *nfit_bdw;
> struct nfit_idt *nfit_idt;
> u16 idt_idx, range_index;
>
> - list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
> - if (nfit_dcr->dcr->region_index != dcr)
> - continue;
> - nfit_mem->dcr = nfit_dcr->dcr;
> - break;
> - }
> -
> - if (!nfit_mem->dcr) {
> - dev_dbg(acpi_desc->dev, "SPA %d missing:%s%s\n",
> - spa->range_index, __to_nfit_memdev(nfit_mem)
> - ? "" : " MEMDEV", nfit_mem->dcr ? "" : " DCR");
> - return -ENODEV;
> - }
> -
> - /*
> - * We've found enough to create an nvdimm, optionally
> - * find an associated BDW
> - */
> - list_add(&nfit_mem->list, &acpi_desc->dimms);
> -
> list_for_each_entry(nfit_bdw, &acpi_desc->bdws, list) {
> if (nfit_bdw->bdw->region_index != dcr)
> continue;
> @@ -508,12 +487,12 @@ static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc,
> }
>
> if (!nfit_mem->bdw)
> - return 0;
> + return;
>
> nfit_mem_find_spa_bdw(acpi_desc, nfit_mem);
>
> if (!nfit_mem->spa_bdw)
> - return 0;
> + return;
>
> range_index = nfit_mem->spa_bdw->range_index;
> list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
> @@ -538,8 +517,6 @@ static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc,
> }
> break;
> }
> -
> - return 0;
> }
>
> static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> @@ -548,7 +525,6 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> struct nfit_mem *nfit_mem, *found;
> struct nfit_memdev *nfit_memdev;
> int type = nfit_spa_type(spa);
> - u16 dcr;
>
> switch (type) {
> case NFIT_SPA_DCR:
> @@ -559,14 +535,18 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> }
>
> list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
> - int rc;
> + struct nfit_dcr *nfit_dcr;
> + u32 device_handle;
> + u16 dcr;
>
> if (nfit_memdev->memdev->range_index != spa->range_index)
> continue;
> found = NULL;
> dcr = nfit_memdev->memdev->region_index;
> + device_handle = nfit_memdev->memdev->device_handle;
> list_for_each_entry(nfit_mem, &acpi_desc->dimms, list)
> - if (__to_nfit_memdev(nfit_mem)->region_index == dcr) {
> + if (__to_nfit_memdev(nfit_mem)->device_handle
> + == device_handle) {
> found = nfit_mem;
> break;
> }
> @@ -579,6 +559,31 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> if (!nfit_mem)
> return -ENOMEM;
> INIT_LIST_HEAD(&nfit_mem->list);
> + list_add(&nfit_mem->list, &acpi_desc->dimms);
> + }
> +
> + list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
> + if (nfit_dcr->dcr->region_index != dcr)
> + continue;
> + /*
> + * Record the control region for the dimm. For
> + * the ACPI 6.1 case, where there are separate
> + * control regions for the pmem vs blk
> + * interfaces, be sure to record the extended
> + * blk details.
> + */
> + if (!nfit_mem->dcr)
> + nfit_mem->dcr = nfit_dcr->dcr;
> + else if (nfit_mem->dcr->windows == 0
> + && nfit_dcr->dcr->windows)
> + nfit_mem->dcr = nfit_dcr->dcr;
> + break;
> + }
> +
> + if (dcr && !nfit_mem->dcr) {
> + dev_err(acpi_desc->dev, "SPA %d missing DCR %d\n",
> + spa->range_index, dcr);
> + return -ENODEV;
> }
>
> if (type == NFIT_SPA_DCR) {
> @@ -595,6 +600,7 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> nfit_mem->idt_dcr = nfit_idt->idt;
> break;
> }
> + nfit_mem_init_bdw(acpi_desc, nfit_mem, spa);
> } else {
> /*
> * A single dimm may belong to multiple SPA-PM
> @@ -603,13 +609,6 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> */
> nfit_mem->memdev_pmem = nfit_memdev->memdev;
> }
> -
> - if (found)
> - continue;
> -
> - rc = nfit_mem_add(acpi_desc, nfit_mem, spa);
> - if (rc)
> - return rc;
> }
>
> return 0;
>
> _______________________________________________
> Linux-nvdimm mailing list
> Linux-nvdimm@lists.01.org
> https://lists.01.org/mailman/listinfo/linux-nvdimm
>
WARNING: multiple messages have this Message-ID (diff)
From: Linda Knippers <linda.knippers@hpe.com>
To: Dan Williams <dan.j.williams@intel.com>, linux-nvdimm@ml01.01.org
Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: Re: [PATCH 1/3] nfit: fix multi-interface dimm handling, acpi6.1 compatibility
Date: Mon, 8 Feb 2016 14:10:58 -0500 [thread overview]
Message-ID: <56B8E842.9080506@hpe.com> (raw)
In-Reply-To: <20160208183058.27820.87950.stgit@dwillia2-desk3.amr.corp.intel.com>
On 2/8/2016 1:30 PM, Dan Williams wrote:
> ACPI 6.1 clarified that multi-interface dimms require multiple control
> region entries (DCRs) per dimm. Previously we were assuming that a
> control region is only present when block-data-windows are present.
We need to give this a quick test with NVDIMM-N because those types of
NVDIMMs have control regions without block-data-windows. We've fixed
bugs related to that assumption a couple of times.
> This implementation was done with an eye to be compatibility with the
> looser ACPI 6.0 interpretation of this table.
>
> 1/ When coalescing the memory device (MEMDEV) tables for a single dimm,
> coalesce on device_handle rather than control region index.
>
> 2/ Whenever we disocver a control region with non-zero block windows
discover
> re-scan for block-data-window (BDW) entries.
>
> We may need to revisit this if a DIMM ever implements a format interface
> outside of blk or pmem, but that is not on the foreseeable horizon.
>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
> drivers/acpi/nfit.c | 71 +++++++++++++++++++++++++--------------------------
> 1 file changed, 35 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
> index ad6d8c6b777e..424b362e8fdc 100644
> --- a/drivers/acpi/nfit.c
> +++ b/drivers/acpi/nfit.c
> @@ -469,37 +469,16 @@ static void nfit_mem_find_spa_bdw(struct acpi_nfit_desc *acpi_desc,
> nfit_mem->bdw = NULL;
> }
>
> -static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc,
> +static void nfit_mem_init_bdw(struct acpi_nfit_desc *acpi_desc,
> struct nfit_mem *nfit_mem, struct acpi_nfit_system_address *spa)
> {
> u16 dcr = __to_nfit_memdev(nfit_mem)->region_index;
> struct nfit_memdev *nfit_memdev;
> struct nfit_flush *nfit_flush;
> - struct nfit_dcr *nfit_dcr;
> struct nfit_bdw *nfit_bdw;
> struct nfit_idt *nfit_idt;
> u16 idt_idx, range_index;
>
> - list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
> - if (nfit_dcr->dcr->region_index != dcr)
> - continue;
> - nfit_mem->dcr = nfit_dcr->dcr;
> - break;
> - }
> -
> - if (!nfit_mem->dcr) {
> - dev_dbg(acpi_desc->dev, "SPA %d missing:%s%s\n",
> - spa->range_index, __to_nfit_memdev(nfit_mem)
> - ? "" : " MEMDEV", nfit_mem->dcr ? "" : " DCR");
> - return -ENODEV;
> - }
> -
> - /*
> - * We've found enough to create an nvdimm, optionally
> - * find an associated BDW
> - */
> - list_add(&nfit_mem->list, &acpi_desc->dimms);
> -
> list_for_each_entry(nfit_bdw, &acpi_desc->bdws, list) {
> if (nfit_bdw->bdw->region_index != dcr)
> continue;
> @@ -508,12 +487,12 @@ static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc,
> }
>
> if (!nfit_mem->bdw)
> - return 0;
> + return;
>
> nfit_mem_find_spa_bdw(acpi_desc, nfit_mem);
>
> if (!nfit_mem->spa_bdw)
> - return 0;
> + return;
>
> range_index = nfit_mem->spa_bdw->range_index;
> list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
> @@ -538,8 +517,6 @@ static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc,
> }
> break;
> }
> -
> - return 0;
> }
>
> static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> @@ -548,7 +525,6 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> struct nfit_mem *nfit_mem, *found;
> struct nfit_memdev *nfit_memdev;
> int type = nfit_spa_type(spa);
> - u16 dcr;
>
> switch (type) {
> case NFIT_SPA_DCR:
> @@ -559,14 +535,18 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> }
>
> list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
> - int rc;
> + struct nfit_dcr *nfit_dcr;
> + u32 device_handle;
> + u16 dcr;
>
> if (nfit_memdev->memdev->range_index != spa->range_index)
> continue;
> found = NULL;
> dcr = nfit_memdev->memdev->region_index;
> + device_handle = nfit_memdev->memdev->device_handle;
> list_for_each_entry(nfit_mem, &acpi_desc->dimms, list)
> - if (__to_nfit_memdev(nfit_mem)->region_index == dcr) {
> + if (__to_nfit_memdev(nfit_mem)->device_handle
> + == device_handle) {
> found = nfit_mem;
> break;
> }
> @@ -579,6 +559,31 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> if (!nfit_mem)
> return -ENOMEM;
> INIT_LIST_HEAD(&nfit_mem->list);
> + list_add(&nfit_mem->list, &acpi_desc->dimms);
> + }
> +
> + list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
> + if (nfit_dcr->dcr->region_index != dcr)
> + continue;
> + /*
> + * Record the control region for the dimm. For
> + * the ACPI 6.1 case, where there are separate
> + * control regions for the pmem vs blk
> + * interfaces, be sure to record the extended
> + * blk details.
> + */
> + if (!nfit_mem->dcr)
> + nfit_mem->dcr = nfit_dcr->dcr;
> + else if (nfit_mem->dcr->windows == 0
> + && nfit_dcr->dcr->windows)
> + nfit_mem->dcr = nfit_dcr->dcr;
> + break;
> + }
> +
> + if (dcr && !nfit_mem->dcr) {
> + dev_err(acpi_desc->dev, "SPA %d missing DCR %d\n",
> + spa->range_index, dcr);
> + return -ENODEV;
> }
>
> if (type == NFIT_SPA_DCR) {
> @@ -595,6 +600,7 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> nfit_mem->idt_dcr = nfit_idt->idt;
> break;
> }
> + nfit_mem_init_bdw(acpi_desc, nfit_mem, spa);
> } else {
> /*
> * A single dimm may belong to multiple SPA-PM
> @@ -603,13 +609,6 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
> */
> nfit_mem->memdev_pmem = nfit_memdev->memdev;
> }
> -
> - if (found)
> - continue;
> -
> - rc = nfit_mem_add(acpi_desc, nfit_mem, spa);
> - if (rc)
> - return rc;
> }
>
> return 0;
>
> _______________________________________________
> Linux-nvdimm mailing list
> Linux-nvdimm@lists.01.org
> https://lists.01.org/mailman/listinfo/linux-nvdimm
>
next prev parent reply other threads:[~2016-02-08 19:11 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-08 18:30 [PATCH 0/3] ACPI 6.1 NFIT Compatibility Dan Williams
2016-02-08 18:30 ` Dan Williams
2016-02-08 18:30 ` [PATCH 1/3] nfit: fix multi-interface dimm handling, acpi6.1 compatibility Dan Williams
2016-02-08 18:30 ` Dan Williams
2016-02-08 19:10 ` Linda Knippers [this message]
2016-02-08 19:10 ` Linda Knippers
2016-02-08 20:23 ` Linda Knippers
2016-02-08 20:23 ` Linda Knippers
2016-02-08 20:37 ` Dan Williams
2016-02-08 20:37 ` Dan Williams
2016-02-08 18:31 ` [PATCH 2/3] nfit, tools/testing/nvdimm: add format interface code definitions Dan Williams
2016-02-08 18:31 ` Dan Williams
2016-02-08 18:31 ` [PATCH 3/3] nfit, tools/testing/nvdimm: test multiple control regions per-dimm Dan Williams
2016-02-08 18:31 ` Dan Williams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56B8E842.9080506@hpe.com \
--to=linda.knippers@hpe.com \
--cc=dan.j.williams@intel.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvdimm@lists.01.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.