On 5/23/26 2:43 AM, Anisa Su wrote:
> Add an alignment gate to cxl_add_pending(): every extent in a tag group
> must have its start_dpa and length aligned to CXL_DCD_EXTENT_ALIGN (SZ_2M,
> the minimum device-dax mapping granularity on every architecture that
> enables CXL DCD).  A misaligned extent makes the resulting dax device
> unusable, so drop the whole group rather than accept a partial allocation
> that would surface a broken dax_resource.
> 
> Based on patches by John Groves.
> 
> Signed-off-by: Ira Weiny <[email protected]>
> Signed-off-by: John Groves <[email protected]>
> Signed-off-by: Anisa Su <[email protected]>
> 
> ---
> Changes:
> [anisa: split out as a separate validation step]
> ---
>  drivers/cxl/core/mbox.c | 39 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
> index e5edc3975e8f..421bd716a273 100644
> --- a/drivers/cxl/core/mbox.c
> +++ b/drivers/cxl/core/mbox.c
> @@ -7,6 +7,7 @@
>  #include <linux/unaligned.h>
>  #include <linux/list.h>
>  #include <linux/list_sort.h>
> +#include <linux/sizes.h>
>  #include <cxlpci.h>
>  #include <cxlmem.h>
>  #include <cxl.h>
> @@ -1280,6 +1281,24 @@ static int add_to_pending_list(struct list_head 
> *pending_list,
>       return 0;
>  }
>  
> +/*
> + * Device-dax requires extent boundaries aligned to its mapping granularity.
> + * Use SZ_2M as a conservative default; a tighter check that queries the
> + * cxl_dax_region / cxl_endpoint_decoder for its actual alignment would be
> + * strictly more correct, but SZ_2M is the minimum device-dax supports on
> + * every architecture that enables CXL DCD today.
> + */
> +#define CXL_DCD_EXTENT_ALIGN SZ_2M

Wonder if this would cause issues in DAX on ARM64 with 64k page size since its 
PMD size is 512M. 

DJ
> +
> +static bool cxl_extent_dcd_aligned(const struct cxl_extent *extent)
> +{
> +     u64 start = le64_to_cpu(extent->start_dpa);
> +     u64 len = le64_to_cpu(extent->length);
> +
> +     return IS_ALIGNED(start, CXL_DCD_EXTENT_ALIGN) &&
> +            IS_ALIGNED(len, CXL_DCD_EXTENT_ALIGN);
> +}
> +
>  /*
>   * Compare two extents by shared_extn_seq (ascending).  list_sort is
>   * stable so when shared_extn_seq is 0 for every entry (non-sharable
> @@ -1352,6 +1371,26 @@ static int cxl_add_pending(struct cxl_memdev_state 
> *mds)
>               extract_tag_group(pending, &tag, &group);
>               list_sort(NULL, &group, extent_seq_compare);
>  
> +             /* Alignment gate — abort the group if any member fails */
> +             bool aligned = true;

declaring var in middle of code

> +             list_for_each_entry(pos, &group, list) {
> +                     if (!cxl_extent_dcd_aligned(pos->extent)) {
> +                             dev_warn(dev,
> +                                      "Tag %pUb: dropping group, extent 
> DPA:%#llx LEN:%#llx not %u-aligned\n",
> +                                      &tag,
> +                                      le64_to_cpu(pos->extent->start_dpa),
> +                                      le64_to_cpu(pos->extent->length),
> +                                      CXL_DCD_EXTENT_ALIGN);
> +                             aligned = false;
> +                             break;
> +                     }
> +             }
> +             if (!aligned) {
> +                     list_for_each_entry_safe(pos, tmp, &group, list)
> +                             delete_extent_node(pos);
> +                     continue;
> +             }
> +
>               u16 logical_seq = 1;

Looks like this one came from a previous patch.


>               list_for_each_entry_safe(pos, tmp, &group, list) {
>                       u16 raw = le16_to_cpu(pos->extent->shared_extn_seq);


Reply via email to