diff mbox series

[1/3] cxl/pci: Store memory capacity values

Message ID 20210611002224.1594913-2-ira.weiny@intel.com
State Superseded
Headers show
Series Query and use Partition Info | expand

Commit Message

Ira Weiny June 11, 2021, 12:22 a.m. UTC
From: Ira Weiny <ira.weiny@intel.com>

The Identify Memory Device command returns information about the
volatile and persistent memory capacities.  Store those values in the
cxl_mem structure for later use.  While at it, reuse the calculation of
the volatile and persistent memory byte values to calculate the ram and
pmem ranges.

Signed-off-by: Ira Weiny <ira.weiny@intel.com>
---
 drivers/cxl/mem.h |  4 ++++
 drivers/cxl/pci.c | 36 +++++++++++++++++++++++++++++++++---
 2 files changed, 37 insertions(+), 3 deletions(-)

Comments

Ben Widawsky June 11, 2021, 5:18 p.m. UTC | #1
On 21-06-10 17:22:22, ira.weiny@intel.com wrote:
> From: Ira Weiny <ira.weiny@intel.com>
> 
> The Identify Memory Device command returns information about the
> volatile and persistent memory capacities.  Store those values in the
> cxl_mem structure for later use.  While at it, reuse the calculation of
> the volatile and persistent memory byte values to calculate the ram and
> pmem ranges.
> 
> Signed-off-by: Ira Weiny <ira.weiny@intel.com>

One comment below that can be taken or left...

Acked-by: Ben Widawsky <ben.widawsky@intel.com>

> ---
>  drivers/cxl/mem.h |  4 ++++
>  drivers/cxl/pci.c | 36 +++++++++++++++++++++++++++++++++---
>  2 files changed, 37 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/cxl/mem.h b/drivers/cxl/mem.h
> index 13868ff7cadf..8bd0d0506b97 100644
> --- a/drivers/cxl/mem.h
> +++ b/drivers/cxl/mem.h
> @@ -75,5 +75,9 @@ struct cxl_mem {
>  
>  	struct range pmem_range;
>  	struct range ram_range;
> +	u64 total_cap_bytes;
> +	u64 volatile_cap_bytes;
> +	u64 persistent_cap_bytes;

I'd either drop 'cap' entirely or type it out. I don't think 'cap' is a
descriptive name.

> +	u64 partition_align_bytes;
>  };
>  #endif /* __CXL_MEM_H__ */
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 5a1705b52278..9995f97d3b28 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -57,6 +57,15 @@ enum opcode {
>  	CXL_MBOX_OP_MAX			= 0x10000
>  };
>  
> +/*
> + * CXL 2.0 - Memory capacity multiplier
> + * See Section 8.2.9.5
> + *
> + * Volatile, Persistent, and Partition capacities are specified to be in
> + * multiples of 256MB - define a multiplier to convert to/from bytes.
> + */
> +#define CXL_CAPACITY_MULTIPLIER SZ_256M
> +
>  /**
>   * struct mbox_cmd - A command to be submitted to hardware.
>   * @opcode: (input) The command set and command submitted to hardware.
> @@ -1542,16 +1551,37 @@ static int cxl_mem_identify(struct cxl_mem *cxlm)
>  	if (rc < 0)
>  		return rc;
>  
> +	cxlm->total_cap_bytes = le64_to_cpu(id.total_capacity);
> +	cxlm->total_cap_bytes *= CXL_CAPACITY_MULTIPLIER;
> +
> +	cxlm->volatile_cap_bytes = le64_to_cpu(id.volatile_capacity);
> +	cxlm->volatile_cap_bytes *= CXL_CAPACITY_MULTIPLIER;
> +
> +	cxlm->persistent_cap_bytes = le64_to_cpu(id.persistent_capacity);
> +	cxlm->persistent_cap_bytes *= CXL_CAPACITY_MULTIPLIER;
> +
> +	cxlm->partition_align_bytes = le64_to_cpu(id.partition_align);
> +	cxlm->partition_align_bytes *= CXL_CAPACITY_MULTIPLIER;
> +
> +	dev_dbg(&cxlm->pdev->dev, "Identify Memory Device\n"
> +		"     total_cap_bytes = %#llx\n"
> +		"     volatile_cap_bytes = %#llx\n"
> +		"     persistent_cap_bytes = %#llx\n"
> +		"     partition_align_bytes = %#llx\n",
> +			cxlm->total_cap_bytes,
> +			cxlm->volatile_cap_bytes,
> +			cxlm->persistent_cap_bytes,
> +			cxlm->partition_align_bytes);
> +
>  	/*
>  	 * TODO: enumerate DPA map, as 'ram' and 'pmem' do not alias.
>  	 * For now, only the capacity is exported in sysfs
>  	 */
>  	cxlm->ram_range.start = 0;
> -	cxlm->ram_range.end = le64_to_cpu(id.volatile_capacity) * SZ_256M - 1;
> +	cxlm->ram_range.end = cxlm->volatile_cap_bytes - 1;
>  
>  	cxlm->pmem_range.start = 0;
> -	cxlm->pmem_range.end =
> -		le64_to_cpu(id.persistent_capacity) * SZ_256M - 1;
> +	cxlm->pmem_range.end = cxlm->persistent_cap_bytes - 1;
>  
>  	cxlm->lsa_size = le32_to_cpu(id.lsa_size);
>  	memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision));
> -- 
> 2.28.0.rc0.12.gb6a658bd00c9
>
Dan Williams June 11, 2021, 5:26 p.m. UTC | #2
On Thu, Jun 10, 2021 at 5:22 PM <ira.weiny@intel.com> wrote:
>
> From: Ira Weiny <ira.weiny@intel.com>
>
> The Identify Memory Device command returns information about the
> volatile and persistent memory capacities.  Store those values in the
> cxl_mem structure for later use.  While at it, reuse the calculation of
> the volatile and persistent memory byte values to calculate the ram and
> pmem ranges.
>
> Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> ---
>  drivers/cxl/mem.h |  4 ++++
>  drivers/cxl/pci.c | 36 +++++++++++++++++++++++++++++++++---
>  2 files changed, 37 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/cxl/mem.h b/drivers/cxl/mem.h
> index 13868ff7cadf..8bd0d0506b97 100644
> --- a/drivers/cxl/mem.h
> +++ b/drivers/cxl/mem.h
> @@ -75,5 +75,9 @@ struct cxl_mem {
>
>         struct range pmem_range;
>         struct range ram_range;
> +       u64 total_cap_bytes;
> +       u64 volatile_cap_bytes;
> +       u64 persistent_cap_bytes;

Hmm, why these fields?

I would expect pmem_range and ram_range can already represent these
values and range_len(pmem_range) + range_len(ram_range) == total
capacity.
Ben Widawsky June 11, 2021, 5:50 p.m. UTC | #3
On 21-06-11 10:26:34, Dan Williams wrote:
> On Thu, Jun 10, 2021 at 5:22 PM <ira.weiny@intel.com> wrote:
> >
> > From: Ira Weiny <ira.weiny@intel.com>
> >
> > The Identify Memory Device command returns information about the
> > volatile and persistent memory capacities.  Store those values in the
> > cxl_mem structure for later use.  While at it, reuse the calculation of
> > the volatile and persistent memory byte values to calculate the ram and
> > pmem ranges.
> >
> > Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> > ---
> >  drivers/cxl/mem.h |  4 ++++
> >  drivers/cxl/pci.c | 36 +++++++++++++++++++++++++++++++++---
> >  2 files changed, 37 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/cxl/mem.h b/drivers/cxl/mem.h
> > index 13868ff7cadf..8bd0d0506b97 100644
> > --- a/drivers/cxl/mem.h
> > +++ b/drivers/cxl/mem.h
> > @@ -75,5 +75,9 @@ struct cxl_mem {
> >
> >         struct range pmem_range;
> >         struct range ram_range;
> > +       u64 total_cap_bytes;
> > +       u64 volatile_cap_bytes;
> > +       u64 persistent_cap_bytes;
> 
> Hmm, why these fields?
> 
> I would expect pmem_range and ram_range can already represent these
> values and range_len(pmem_range) + range_len(ram_range) == total
> capacity.

So the way Ira described it (AIUI), pmem_range will be the total partitioned
amount, while persistent_cap_bytes is min(info.persistent capacity, pmem_range)
(same for volatile). But perhaps I misunderstood.
Ira Weiny June 11, 2021, 7:58 p.m. UTC | #4
On Fri, Jun 11, 2021 at 10:50:30AM -0700, Widawsky, Ben wrote:
> On 21-06-11 10:26:34, Dan Williams wrote:
> > On Thu, Jun 10, 2021 at 5:22 PM <ira.weiny@intel.com> wrote:
> > >
> > > From: Ira Weiny <ira.weiny@intel.com>
> > >
> > > The Identify Memory Device command returns information about the
> > > volatile and persistent memory capacities.  Store those values in the
> > > cxl_mem structure for later use.  While at it, reuse the calculation of
> > > the volatile and persistent memory byte values to calculate the ram and
> > > pmem ranges.
> > >
> > > Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> > > ---
> > >  drivers/cxl/mem.h |  4 ++++
> > >  drivers/cxl/pci.c | 36 +++++++++++++++++++++++++++++++++---
> > >  2 files changed, 37 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/cxl/mem.h b/drivers/cxl/mem.h
> > > index 13868ff7cadf..8bd0d0506b97 100644
> > > --- a/drivers/cxl/mem.h
> > > +++ b/drivers/cxl/mem.h
> > > @@ -75,5 +75,9 @@ struct cxl_mem {
> > >
> > >         struct range pmem_range;
> > >         struct range ram_range;
> > > +       u64 total_cap_bytes;
> > > +       u64 volatile_cap_bytes;
> > > +       u64 persistent_cap_bytes;
> > 
> > Hmm, why these fields?
> > 
> > I would expect pmem_range and ram_range can already represent these
> > values and range_len(pmem_range) + range_len(ram_range) == total
> > capacity.
> 
> So the way Ira described it (AIUI), pmem_range will be the total partitioned
> amount, while persistent_cap_bytes is min(info.persistent capacity, pmem_range)
> (same for volatile). But perhaps I misunderstood.

Yes persistent is 'persistent only'...  so s/cap/only/ is probably better name.

pmem_range.len() may == persistent_cap_bytes.  But does not need to.

Ira
diff mbox series

Patch

diff --git a/drivers/cxl/mem.h b/drivers/cxl/mem.h
index 13868ff7cadf..8bd0d0506b97 100644
--- a/drivers/cxl/mem.h
+++ b/drivers/cxl/mem.h
@@ -75,5 +75,9 @@  struct cxl_mem {
 
 	struct range pmem_range;
 	struct range ram_range;
+	u64 total_cap_bytes;
+	u64 volatile_cap_bytes;
+	u64 persistent_cap_bytes;
+	u64 partition_align_bytes;
 };
 #endif /* __CXL_MEM_H__ */
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 5a1705b52278..9995f97d3b28 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -57,6 +57,15 @@  enum opcode {
 	CXL_MBOX_OP_MAX			= 0x10000
 };
 
+/*
+ * CXL 2.0 - Memory capacity multiplier
+ * See Section 8.2.9.5
+ *
+ * Volatile, Persistent, and Partition capacities are specified to be in
+ * multiples of 256MB - define a multiplier to convert to/from bytes.
+ */
+#define CXL_CAPACITY_MULTIPLIER SZ_256M
+
 /**
  * struct mbox_cmd - A command to be submitted to hardware.
  * @opcode: (input) The command set and command submitted to hardware.
@@ -1542,16 +1551,37 @@  static int cxl_mem_identify(struct cxl_mem *cxlm)
 	if (rc < 0)
 		return rc;
 
+	cxlm->total_cap_bytes = le64_to_cpu(id.total_capacity);
+	cxlm->total_cap_bytes *= CXL_CAPACITY_MULTIPLIER;
+
+	cxlm->volatile_cap_bytes = le64_to_cpu(id.volatile_capacity);
+	cxlm->volatile_cap_bytes *= CXL_CAPACITY_MULTIPLIER;
+
+	cxlm->persistent_cap_bytes = le64_to_cpu(id.persistent_capacity);
+	cxlm->persistent_cap_bytes *= CXL_CAPACITY_MULTIPLIER;
+
+	cxlm->partition_align_bytes = le64_to_cpu(id.partition_align);
+	cxlm->partition_align_bytes *= CXL_CAPACITY_MULTIPLIER;
+
+	dev_dbg(&cxlm->pdev->dev, "Identify Memory Device\n"
+		"     total_cap_bytes = %#llx\n"
+		"     volatile_cap_bytes = %#llx\n"
+		"     persistent_cap_bytes = %#llx\n"
+		"     partition_align_bytes = %#llx\n",
+			cxlm->total_cap_bytes,
+			cxlm->volatile_cap_bytes,
+			cxlm->persistent_cap_bytes,
+			cxlm->partition_align_bytes);
+
 	/*
 	 * TODO: enumerate DPA map, as 'ram' and 'pmem' do not alias.
 	 * For now, only the capacity is exported in sysfs
 	 */
 	cxlm->ram_range.start = 0;
-	cxlm->ram_range.end = le64_to_cpu(id.volatile_capacity) * SZ_256M - 1;
+	cxlm->ram_range.end = cxlm->volatile_cap_bytes - 1;
 
 	cxlm->pmem_range.start = 0;
-	cxlm->pmem_range.end =
-		le64_to_cpu(id.persistent_capacity) * SZ_256M - 1;
+	cxlm->pmem_range.end = cxlm->persistent_cap_bytes - 1;
 
 	cxlm->lsa_size = le32_to_cpu(id.lsa_size);
 	memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision));