diff mbox series

[ndctl,v3,5/6] libcxl: add interfaces for SET_PARTITION_INFO mailbox command

Message ID e98fa18538c42c40b120d5c22da655d199d0329d.1642535478.git.alison.schofield@intel.com (mailing list archive)
State Superseded
Headers show
Series Add partitioning support for CXL memdevs | expand

Commit Message

Alison Schofield Jan. 18, 2022, 8:25 p.m. UTC
From: Alison Schofield <alison.schofield@intel.com>

Users may want the ability to change the partition layout of a CXL
memory device.

Add interfaces to libcxl to allocate and send a SET_PARTITION_INFO
mailbox as defined in the CXL 2.0 specification.

Signed-off-by: Alison Schofield <alison.schofield@intel.com>
---
 cxl/lib/libcxl.c   | 50 ++++++++++++++++++++++++++++++++++++++++++++++
 cxl/lib/libcxl.sym |  5 +++++
 cxl/lib/private.h  |  8 ++++++++
 cxl/libcxl.h       |  5 +++++
 4 files changed, 68 insertions(+)

Comments

Dan Williams Jan. 26, 2022, 11:41 p.m. UTC | #1
On Tue, Jan 18, 2022 at 12:20 PM <alison.schofield@intel.com> wrote:
>
> From: Alison Schofield <alison.schofield@intel.com>
>
> Users may want the ability to change the partition layout of a CXL
> memory device.
>
> Add interfaces to libcxl to allocate and send a SET_PARTITION_INFO
> mailbox as defined in the CXL 2.0 specification.
>
> Signed-off-by: Alison Schofield <alison.schofield@intel.com>
> ---
>  cxl/lib/libcxl.c   | 50 ++++++++++++++++++++++++++++++++++++++++++++++
>  cxl/lib/libcxl.sym |  5 +++++
>  cxl/lib/private.h  |  8 ++++++++
>  cxl/libcxl.h       |  5 +++++
>  4 files changed, 68 insertions(+)
>
> diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
> index 5b1fc32..5a5b189 100644
> --- a/cxl/lib/libcxl.c
> +++ b/cxl/lib/libcxl.c
> @@ -1230,6 +1230,21 @@ cxl_cmd_partition_info_get_next_persistent_bytes(struct cxl_cmd *cmd)
>         cmd_partition_get_capacity_field(cmd, next_persistent_cap);
>  }
>
> +CXL_EXPORT struct cxl_cmd *cxl_cmd_new_set_partition_info(struct cxl_memdev *memdev,
> +               unsigned long long volatile_capacity, int flags)
> +{
> +       struct cxl_cmd_set_partition_info *set_partition;
> +       struct cxl_cmd *cmd;
> +
> +       cmd = cxl_cmd_new_generic(memdev,
> +                       CXL_MEM_COMMAND_ID_SET_PARTITION_INFO);
> +
> +       set_partition = (struct cxl_cmd_set_partition_info *)cmd->send_cmd->in.payload;

->in.payload is a 'void *', no casting required.


> +       set_partition->volatile_capacity = cpu_to_le64(volatile_capacity);
> +       set_partition->flags = flags;

This has the potential to bite if users get accustomed passing in raw
values directly... more below.

> +       return cmd;
> +}
> +
>  CXL_EXPORT int cxl_cmd_submit(struct cxl_cmd *cmd)
>  {
>         struct cxl_memdev *memdev = cmd->memdev;
> @@ -1428,3 +1443,38 @@ CXL_EXPORT int cxl_memdev_read_label(struct cxl_memdev *memdev, void *buf,
>  {
>         return lsa_op(memdev, LSA_OP_GET, buf, length, offset);
>  }
> +
> +CXL_EXPORT int cxl_memdev_set_partition_info(struct cxl_memdev *memdev,
> +              unsigned long long volatile_capacity, int flags)
> +{
> +       struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
> +       struct cxl_cmd *cmd;
> +       int rc;
> +
> +       dbg(ctx, "%s: enter cap: %llx, flags %d\n", __func__,
> +               volatile_capacity, flags);
> +
> +       cmd = cxl_cmd_new_set_partition_info(memdev,
> +                       volatile_capacity / CXL_CAPACITY_MULTIPLIER, flags);

Given that the get-partition-info helpers emit 'bytes' I think it
would make sense for the set-partition-info to take bytes, i.e. move
the conversion to the 256MB shifted value internal to
xl_cmd_new_set_partition_info().


> +       if (!cmd)
> +               return -ENXIO;
> +
> +       rc = cxl_cmd_submit(cmd);
> +       if (rc < 0) {
> +               err(ctx, "cmd submission failed: %s\n", strerror(-rc));
> +               goto err;
> +       }
> +       rc = cxl_cmd_get_mbox_status(cmd);
> +       if (rc != 0) {
> +               err(ctx, "%s: mbox status: %d\n", __func__, rc);
> +               rc = -ENXIO;
> +       }
> +err:
> +       cxl_cmd_unref(cmd);
> +       return rc;
> +}
> +
> +CXL_EXPORT int cxl_cmd_partition_info_flag_immediate(void)
> +{
> +       return CXL_CMD_SET_PARTITION_INFO_FLAG_IMMEDIATE;
> +}

I don't understand what this is for?

Let's back up. In order to future proof against spec changes, and
endianness, struct packing and all other weird things that make struct
ABIs hard to maintain compatibility the ndctl project adopts the
libabc template of just not letting library consumers see any raw data
structures or bit fields by default [1]. For a situation like this
since the command only has one flag that affects the mode of operation
I would just go ahead and define an enum for that explicitly.

enum cxl_setpartition_mode {
    CXL_SETPART_NONE,
    CXL_SETPART_NEXTBOOT,
    CXL_SETPART_IMMEDIATE,
};

Then the main function prototype becomes:

int cxl_cmd_new_setpartition(struct cxl_memdev *memdev, unsigned long
long volatile_capacity);

...with a new:

int cxl_cmd_setpartition_set_mode(struct cxl_cmd *cmd, enum
cxl_setpartition_mode mode);

...and it becomes impossible for users to pass unsupported flag
values. If the specification later on adds more flags then we can add
more:

int cxl_cmd_setpartition_set_<X>(struct cxl_cmd *cmd, enum
cxl_setpartition_X x);

...style helpers.

Note, I was thinking CXL_SETPART_NONE is there to catch API users that
forget to set a mode, but I also don't mind skipping that and just
defaulting cxl_cmd_new_setpartition() to CXL_SETPART_NEXTBOOT, up to
you.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/kay/libabc.git/tree/README#n99
Alison Schofield Jan. 27, 2022, 8:50 p.m. UTC | #2
Hi Dan,
Thanks for the review. I'm still working thru this, but a clarifying
question below...

On Wed, Jan 26, 2022 at 03:41:14PM -0800, Dan Williams wrote:
> On Tue, Jan 18, 2022 at 12:20 PM <alison.schofield@intel.com> wrote:
> >
> > From: Alison Schofield <alison.schofield@intel.com>
> >
> > Users may want the ability to change the partition layout of a CXL
> > memory device.
> >
> > Add interfaces to libcxl to allocate and send a SET_PARTITION_INFO
> > mailbox as defined in the CXL 2.0 specification.
> >
> > Signed-off-by: Alison Schofield <alison.schofield@intel.com>
> > ---
> >  cxl/lib/libcxl.c   | 50 ++++++++++++++++++++++++++++++++++++++++++++++
> >  cxl/lib/libcxl.sym |  5 +++++
> >  cxl/lib/private.h  |  8 ++++++++
> >  cxl/libcxl.h       |  5 +++++
> >  4 files changed, 68 insertions(+)
> >
snip
> 
> 
> I don't understand what this is for?
> 
> Let's back up. In order to future proof against spec changes, and
> endianness, struct packing and all other weird things that make struct
> ABIs hard to maintain compatibility the ndctl project adopts the
> libabc template of just not letting library consumers see any raw data
> structures or bit fields by default [1]. For a situation like this
> since the command only has one flag that affects the mode of operation
> I would just go ahead and define an enum for that explicitly.
> 
> enum cxl_setpartition_mode {
>     CXL_SETPART_NONE,
>     CXL_SETPART_NEXTBOOT,
>     CXL_SETPART_IMMEDIATE,
> };
> 
> Then the main function prototype becomes:
> 
> int cxl_cmd_new_setpartition(struct cxl_memdev *memdev, unsigned long
> long volatile_capacity);
> 
> ...with a new:
> 
> int cxl_cmd_setpartition_set_mode(struct cxl_cmd *cmd, enum
> cxl_setpartition_mode mode);
>

I don't understand setting of the mode separately. Can it be:

int cxl_cmd_new_setpartition(struct cxl_memdev *memdev,
			     unsigned long long volatile_capacity,
			     enum cxl_setpartition_mode mode);



> ...and it becomes impossible for users to pass unsupported flag
> values. If the specification later on adds more flags then we can add
> more:
> 
> int cxl_cmd_setpartition_set_<X>(struct cxl_cmd *cmd, enum
> cxl_setpartition_X x);
> 
> ...style helpers.
> 
> Note, I was thinking CXL_SETPART_NONE is there to catch API users that
> forget to set a mode, but I also don't mind skipping that and just
> defaulting cxl_cmd_new_setpartition() to CXL_SETPART_NEXTBOOT, up to
> you.
> 
> [1]: https://git.kernel.org/pub/scm/linux/kernel/git/kay/libabc.git/tree/README#n99
Dan Williams Feb. 1, 2022, 1:24 a.m. UTC | #3
On Thu, Jan 27, 2022 at 12:46 PM Alison Schofield
<alison.schofield@intel.com> wrote:
>
> Hi Dan,
> Thanks for the review. I'm still working thru this, but a clarifying
> question below...
>
> On Wed, Jan 26, 2022 at 03:41:14PM -0800, Dan Williams wrote:
> > On Tue, Jan 18, 2022 at 12:20 PM <alison.schofield@intel.com> wrote:
> > >
> > > From: Alison Schofield <alison.schofield@intel.com>
> > >
> > > Users may want the ability to change the partition layout of a CXL
> > > memory device.
> > >
> > > Add interfaces to libcxl to allocate and send a SET_PARTITION_INFO
> > > mailbox as defined in the CXL 2.0 specification.
> > >
> > > Signed-off-by: Alison Schofield <alison.schofield@intel.com>
> > > ---
> > >  cxl/lib/libcxl.c   | 50 ++++++++++++++++++++++++++++++++++++++++++++++
> > >  cxl/lib/libcxl.sym |  5 +++++
> > >  cxl/lib/private.h  |  8 ++++++++
> > >  cxl/libcxl.h       |  5 +++++
> > >  4 files changed, 68 insertions(+)
> > >
> snip
> >
> >
> > I don't understand what this is for?
> >
> > Let's back up. In order to future proof against spec changes, and
> > endianness, struct packing and all other weird things that make struct
> > ABIs hard to maintain compatibility the ndctl project adopts the
> > libabc template of just not letting library consumers see any raw data
> > structures or bit fields by default [1]. For a situation like this
> > since the command only has one flag that affects the mode of operation
> > I would just go ahead and define an enum for that explicitly.
> >
> > enum cxl_setpartition_mode {
> >     CXL_SETPART_NONE,
> >     CXL_SETPART_NEXTBOOT,
> >     CXL_SETPART_IMMEDIATE,
> > };
> >
> > Then the main function prototype becomes:
> >
> > int cxl_cmd_new_setpartition(struct cxl_memdev *memdev, unsigned long
> > long volatile_capacity);
> >
> > ...with a new:
> >
> > int cxl_cmd_setpartition_set_mode(struct cxl_cmd *cmd, enum
> > cxl_setpartition_mode mode);
> >
>
> I don't understand setting of the mode separately. Can it be:
>
> int cxl_cmd_new_setpartition(struct cxl_memdev *memdev,
>                              unsigned long long volatile_capacity,
>                              enum cxl_setpartition_mode mode);

It could be, but what happens when the specification defines a new
flag for this command? Then we would have cxl_cmd_new_setpartition()
and cxl_cmd_new_setpartition2()  to add the new parameters. A helper
function after establishing the cxl_cmd context lets you have
flexibility to extend the base command by as many new flags and modes
that come along... hopefully none, but you never know.
Alison Schofield Feb. 1, 2022, 1:25 a.m. UTC | #4
Dan, One follow up below...

On Wed, Jan 26, 2022 at 03:41:14PM -0800, Dan Williams wrote:
> On Tue, Jan 18, 2022 at 12:20 PM <alison.schofield@intel.com> wrote:
> >
> > From: Alison Schofield <alison.schofield@intel.com>
> >
> > Users may want the ability to change the partition layout of a CXL
> > memory device.
> >
> > Add interfaces to libcxl to allocate and send a SET_PARTITION_INFO
> > mailbox as defined in the CXL 2.0 specification.
> >
> > Signed-off-by: Alison Schofield <alison.schofield@intel.com>
> > ---
> >  cxl/lib/libcxl.c   | 50 ++++++++++++++++++++++++++++++++++++++++++++++
> >  cxl/lib/libcxl.sym |  5 +++++
> >  cxl/lib/private.h  |  8 ++++++++
> >  cxl/libcxl.h       |  5 +++++
> >  4 files changed, 68 insertions(+)
> >
> > diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
> > index 5b1fc32..5a5b189 100644
> > --- a/cxl/lib/libcxl.c
> > +++ b/cxl/lib/libcxl.c
> > @@ -1230,6 +1230,21 @@ cxl_cmd_partition_info_get_next_persistent_bytes(struct cxl_cmd *cmd)
> >         cmd_partition_get_capacity_field(cmd, next_persistent_cap);
> >  }
> >
> > +CXL_EXPORT struct cxl_cmd *cxl_cmd_new_set_partition_info(struct cxl_memdev *memdev,
> > +               unsigned long long volatile_capacity, int flags)
> > +{
> > +       struct cxl_cmd_set_partition_info *set_partition;
> > +       struct cxl_cmd *cmd;
> > +
> > +       cmd = cxl_cmd_new_generic(memdev,
> > +                       CXL_MEM_COMMAND_ID_SET_PARTITION_INFO);
> > +
> > +       set_partition = (struct cxl_cmd_set_partition_info *)cmd->send_cmd->in.payload;
> 
> ->in.payload is a 'void *', no casting required.
> 

send_cmd->in.payload is a __u64 so this cast is needed.

Of course, I wondered what Dan was thinking ;) and I see that struct
cxl_cmd's input_payload is indeed a 'void *'.

I believe this is the correct payload here, umm..  because it works ;)

But - let me know if you suspect something is off here.

Thanks!




snip
>
Dan Williams Feb. 1, 2022, 1:32 a.m. UTC | #5
On Mon, Jan 31, 2022 at 5:20 PM Alison Schofield
<alison.schofield@intel.com> wrote:
>
> Dan, One follow up below...
>
> On Wed, Jan 26, 2022 at 03:41:14PM -0800, Dan Williams wrote:
> > On Tue, Jan 18, 2022 at 12:20 PM <alison.schofield@intel.com> wrote:
> > >
> > > From: Alison Schofield <alison.schofield@intel.com>
> > >
> > > Users may want the ability to change the partition layout of a CXL
> > > memory device.
> > >
> > > Add interfaces to libcxl to allocate and send a SET_PARTITION_INFO
> > > mailbox as defined in the CXL 2.0 specification.
> > >
> > > Signed-off-by: Alison Schofield <alison.schofield@intel.com>
> > > ---
> > >  cxl/lib/libcxl.c   | 50 ++++++++++++++++++++++++++++++++++++++++++++++
> > >  cxl/lib/libcxl.sym |  5 +++++
> > >  cxl/lib/private.h  |  8 ++++++++
> > >  cxl/libcxl.h       |  5 +++++
> > >  4 files changed, 68 insertions(+)
> > >
> > > diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
> > > index 5b1fc32..5a5b189 100644
> > > --- a/cxl/lib/libcxl.c
> > > +++ b/cxl/lib/libcxl.c
> > > @@ -1230,6 +1230,21 @@ cxl_cmd_partition_info_get_next_persistent_bytes(struct cxl_cmd *cmd)
> > >         cmd_partition_get_capacity_field(cmd, next_persistent_cap);
> > >  }
> > >
> > > +CXL_EXPORT struct cxl_cmd *cxl_cmd_new_set_partition_info(struct cxl_memdev *memdev,
> > > +               unsigned long long volatile_capacity, int flags)
> > > +{
> > > +       struct cxl_cmd_set_partition_info *set_partition;
> > > +       struct cxl_cmd *cmd;
> > > +
> > > +       cmd = cxl_cmd_new_generic(memdev,
> > > +                       CXL_MEM_COMMAND_ID_SET_PARTITION_INFO);
> > > +
> > > +       set_partition = (struct cxl_cmd_set_partition_info *)cmd->send_cmd->in.payload;
> >
> > ->in.payload is a 'void *', no casting required.
> >
>
> send_cmd->in.payload is a __u64 so this cast is needed.
>
> Of course, I wondered what Dan was thinking ;) and I see that struct
> cxl_cmd's input_payload is indeed a 'void *'.
>
> I believe this is the correct payload here, umm..  because it works ;)
>
> But - let me know if you suspect something is off here.

You're right...

...however :), I think this casting is what the core
cxl_cmd_alloc_send() helper is doing for everyone when it does:

cmd->send_cmd->in.payload = (u64)cmd->input_payload;

...so cxl_cmd_new_set_partition_info() can safely switch to the
shorter cmd->input_payload and drop its own redundant local casting.
Alison Schofield Feb. 1, 2022, 1:34 a.m. UTC | #6
> > snip
> > >
> > >
> > > I don't understand what this is for?
> > >
> > > Let's back up. In order to future proof against spec changes, and
> > > endianness, struct packing and all other weird things that make struct
> > > ABIs hard to maintain compatibility the ndctl project adopts the
> > > libabc template of just not letting library consumers see any raw data
> > > structures or bit fields by default [1]. For a situation like this
> > > since the command only has one flag that affects the mode of operation
> > > I would just go ahead and define an enum for that explicitly.
> > >
> > > enum cxl_setpartition_mode {
> > >     CXL_SETPART_NONE,
> > >     CXL_SETPART_NEXTBOOT,
> > >     CXL_SETPART_IMMEDIATE,
> > > };
> > >
> > > Then the main function prototype becomes:
> > >
> > > int cxl_cmd_new_setpartition(struct cxl_memdev *memdev, unsigned long
> > > long volatile_capacity);
> > >
> > > ...with a new:
> > >
> > > int cxl_cmd_setpartition_set_mode(struct cxl_cmd *cmd, enum
> > > cxl_setpartition_mode mode);
> > >
> >
> > I don't understand setting of the mode separately. Can it be:
> >
> > int cxl_cmd_new_setpartition(struct cxl_memdev *memdev,
> >                              unsigned long long volatile_capacity,
> >                              enum cxl_setpartition_mode mode);
> 
> It could be, but what happens when the specification defines a new
> flag for this command? Then we would have cxl_cmd_new_setpartition()
> and cxl_cmd_new_setpartition2()  to add the new parameters. A helper
> function after establishing the cxl_cmd context lets you have
> flexibility to extend the base command by as many new flags and modes
> that come along... hopefully none, but you never know.

Got it. Doing the 'new' followed by 'mode' set up you suggested.
(Sorry, I didn't update this thread after our offline chat.)
diff mbox series

Patch

diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
index 5b1fc32..5a5b189 100644
--- a/cxl/lib/libcxl.c
+++ b/cxl/lib/libcxl.c
@@ -1230,6 +1230,21 @@  cxl_cmd_partition_info_get_next_persistent_bytes(struct cxl_cmd *cmd)
 	cmd_partition_get_capacity_field(cmd, next_persistent_cap);
 }
 
+CXL_EXPORT struct cxl_cmd *cxl_cmd_new_set_partition_info(struct cxl_memdev *memdev,
+		unsigned long long volatile_capacity, int flags)
+{
+	struct cxl_cmd_set_partition_info *set_partition;
+	struct cxl_cmd *cmd;
+
+	cmd = cxl_cmd_new_generic(memdev,
+			CXL_MEM_COMMAND_ID_SET_PARTITION_INFO);
+
+	set_partition = (struct cxl_cmd_set_partition_info *)cmd->send_cmd->in.payload;
+	set_partition->volatile_capacity = cpu_to_le64(volatile_capacity);
+	set_partition->flags = flags;
+	return cmd;
+}
+
 CXL_EXPORT int cxl_cmd_submit(struct cxl_cmd *cmd)
 {
 	struct cxl_memdev *memdev = cmd->memdev;
@@ -1428,3 +1443,38 @@  CXL_EXPORT int cxl_memdev_read_label(struct cxl_memdev *memdev, void *buf,
 {
 	return lsa_op(memdev, LSA_OP_GET, buf, length, offset);
 }
+
+CXL_EXPORT int cxl_memdev_set_partition_info(struct cxl_memdev *memdev,
+	       unsigned long long volatile_capacity, int flags)
+{
+	struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
+	struct cxl_cmd *cmd;
+	int rc;
+
+	dbg(ctx, "%s: enter cap: %llx, flags %d\n", __func__,
+		volatile_capacity, flags);
+
+	cmd = cxl_cmd_new_set_partition_info(memdev,
+			volatile_capacity / CXL_CAPACITY_MULTIPLIER, flags);
+	if (!cmd)
+		return -ENXIO;
+
+	rc = cxl_cmd_submit(cmd);
+	if (rc < 0) {
+		err(ctx, "cmd submission failed: %s\n", strerror(-rc));
+		goto err;
+	}
+	rc = cxl_cmd_get_mbox_status(cmd);
+	if (rc != 0) {
+		err(ctx, "%s: mbox status: %d\n", __func__, rc);
+		rc = -ENXIO;
+	}
+err:
+	cxl_cmd_unref(cmd);
+	return rc;
+}
+
+CXL_EXPORT int cxl_cmd_partition_info_flag_immediate(void)
+{
+	return CXL_CMD_SET_PARTITION_INFO_FLAG_IMMEDIATE;
+}
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
index b7e969f..0ce931d 100644
--- a/cxl/lib/libcxl.sym
+++ b/cxl/lib/libcxl.sym
@@ -78,6 +78,11 @@  global:
 	cxl_cmd_partition_info_get_active_persistent_bytes;
 	cxl_cmd_partition_info_get_next_volatile_bytes;
 	cxl_cmd_partition_info_get_next_persistent_bytes;
+	cxl_cmd_new_set_partition_info;
+	cxl_memdev_set_partition_info;
+	cxl_cmd_partition_info_flag_none;
+	cxl_cmd_partition_info_flag_immediate;
+
 local:
         *;
 };
diff --git a/cxl/lib/private.h b/cxl/lib/private.h
index dd9234f..4da8ea7 100644
--- a/cxl/lib/private.h
+++ b/cxl/lib/private.h
@@ -114,6 +114,14 @@  struct cxl_cmd_get_partition_info {
 
 #define CXL_CAPACITY_MULTIPLIER		SZ_256M
 
+struct cxl_cmd_set_partition_info {
+	le64 volatile_capacity;
+	u8 flags;
+} __attribute__((packed));
+
+/* CXL 2.0 8.2.9.5.2 Set Partition Info */
+#define CXL_CMD_SET_PARTITION_INFO_FLAG_IMMEDIATE			BIT(0)
+
 /* CXL 2.0 8.2.9.5.3 Byte 0 Health Status */
 #define CXL_CMD_HEALTH_INFO_STATUS_MAINTENANCE_NEEDED_MASK		BIT(0)
 #define CXL_CMD_HEALTH_INFO_STATUS_PERFORMANCE_DEGRADED_MASK		BIT(1)
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
index 46f99fb..9b0a599 100644
--- a/cxl/libcxl.h
+++ b/cxl/libcxl.h
@@ -50,6 +50,8 @@  int cxl_memdev_read_label(struct cxl_memdev *memdev, void *buf, size_t length,
 		size_t offset);
 int cxl_memdev_write_label(struct cxl_memdev *memdev, void *buf, size_t length,
 		size_t offset);
+int cxl_memdev_set_partition_info(struct cxl_memdev *memdev,
+		unsigned long long volatile_capacity, int flags);
 
 #define cxl_memdev_foreach(ctx, memdev) \
         for (memdev = cxl_memdev_get_first(ctx); \
@@ -117,6 +119,9 @@  unsigned long long cxl_cmd_partition_info_get_active_volatile_bytes(struct cxl_c
 unsigned long long cxl_cmd_partition_info_get_active_persistent_bytes(struct cxl_cmd *cmd);
 unsigned long long cxl_cmd_partition_info_get_next_volatile_bytes(struct cxl_cmd *cmd);
 unsigned long long cxl_cmd_partition_info_get_next_persistent_bytes(struct cxl_cmd *cmd);
+struct cxl_cmd *cxl_cmd_new_set_partition_info(struct cxl_memdev *memdev,
+		unsigned long long volatile_capacity, int flags);
+int cxl_cmd_partition_info_flag_immediate(void);
 
 #ifdef __cplusplus
 } /* extern "C" */