On 12/5/24 6:10 PM, Alison Schofield wrote:
> On Thu, Dec 05, 2024 at 12:14:56AM +0800, Li Ming wrote:
>> If CONFIG_MEMORY_HOTREMOVE is disabled by kernel, memblocks will not be
>> removed, so 'dax offline-memory all' will output below error logs:
>>
>>   libdaxctl: offline_one_memblock: dax0.0: Failed to offline 
>> /sys/devices/system/node/node6/memory371/state: Invalid argument
>>   dax0.0: failed to offline memory: Invalid argument
>>   error offlining memory: Invalid argument
>>   offlined memory for 0 devices
>>
>> The log does not clearly show why the command failed. So checking if the
>> target memblock is removable before offlining it by querying
>> '/sys/devices/system/node/nodeX/memoryY/removable', then output specific
>> logs if the memblock is unremovable, output will be:
>>
>>   libdaxctl: offline_one_memblock: dax0.0: memory371 is unremovable
>>   dax0.0: failed to offline memory: Operation not supported
>>   error offlining memory: Operation not supported
>>   offlined memory for 0 devices
>>
> 
> Hi Ming,
> 
> This led me to catch up on movable and removable in DAX context.
> Not all 'Movable' DAX memory is 'Removable' right?
> 
> Would it be useful to add 'removable' to the daxctl list json:
> 
> # daxctl list
> [
>   {
>     "chardev":"dax0.0",
>     "size":536870912,
>     "target_node":0,
>     "align":2097152,
>     "mode":"system-ram",
>     "online_memblocks":4,
>     "total_memblocks":4,
>     "movable":true
>     "removable":false  <----

Maybe adding some documentation and explaining the two fields? Otherwise it may 
get confusing.

DJ

>   }
> ]
> 
> You've already added the helper to discover removable.
> 
> Otherwise, LGTM,
> Reviewed-by: Alison Schofield <alison.schofi...@intel.com>
> 
> 
>> Besides, delay to set up string 'path' for offlining memblock operation,
>> because string 'path' is stored in 'mem->mem_buf' which is a shared
>> buffer, it will be used in memblock_is_removable().
>>
>> Signed-off-by: Li Ming <ming...@zohomail.com>
>> ---
>>  daxctl/lib/libdaxctl.c | 52 ++++++++++++++++++++++++++++++++++++------
>>  1 file changed, 45 insertions(+), 7 deletions(-)
>>
>> diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
>> index 9fbefe2e8329..b7fa0de0b73d 100644
>> --- a/daxctl/lib/libdaxctl.c
>> +++ b/daxctl/lib/libdaxctl.c
>> @@ -1310,6 +1310,37 @@ static int memblock_is_online(struct daxctl_memory 
>> *mem, char *memblock)
>>      return 0;
>>  }
>>  
>> +static int memblock_is_removable(struct daxctl_memory *mem, char *memblock)
>> +{
>> +    struct daxctl_dev *dev = daxctl_memory_get_dev(mem);
>> +    const char *devname = daxctl_dev_get_devname(dev);
>> +    struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
>> +    int len = mem->buf_len, rc;
>> +    char buf[SYSFS_ATTR_SIZE];
>> +    char *path = mem->mem_buf;
>> +    const char *node_path;
>> +
>> +    node_path = daxctl_memory_get_node_path(mem);
>> +    if (!node_path)
>> +            return -ENXIO;
>> +
>> +    rc = snprintf(path, len, "%s/%s/removable", node_path, memblock);
>> +    if (rc < 0)
>> +            return -ENOMEM;
>> +
>> +    rc = sysfs_read_attr(ctx, path, buf);
>> +    if (rc) {
>> +            err(ctx, "%s: Failed to read %s: %s\n",
>> +                    devname, path, strerror(-rc));
>> +            return rc;
>> +    }
>> +
>> +    if (strtoul(buf, NULL, 0) == 0)
>> +            return -EOPNOTSUPP;
>> +
>> +    return 0;
>> +}
>> +
>>  static int online_one_memblock(struct daxctl_memory *mem, char *memblock,
>>              enum memory_zones zone, int *status)
>>  {
>> @@ -1362,6 +1393,20 @@ static int offline_one_memblock(struct daxctl_memory 
>> *mem, char *memblock)
>>      char *path = mem->mem_buf;
>>      const char *node_path;
>>  
>> +    /* if already offline, there is nothing to do */
>> +    rc = memblock_is_online(mem, memblock);
>> +    if (rc < 0)
>> +            return rc;
>> +    if (!rc)
>> +            return 1;
>> +
>> +    rc = memblock_is_removable(mem, memblock);
>> +    if (rc) {
>> +            if (rc == -EOPNOTSUPP)
>> +                    err(ctx, "%s: %s is unremovable\n", devname, memblock);
>> +            return rc;
>> +    }
>> +
>>      node_path = daxctl_memory_get_node_path(mem);
>>      if (!node_path)
>>              return -ENXIO;
>> @@ -1370,13 +1415,6 @@ static int offline_one_memblock(struct daxctl_memory 
>> *mem, char *memblock)
>>      if (rc < 0)
>>              return -ENOMEM;
>>  
>> -    /* if already offline, there is nothing to do */
>> -    rc = memblock_is_online(mem, memblock);
>> -    if (rc < 0)
>> -            return rc;
>> -    if (!rc)
>> -            return 1;
>> -
>>      rc = sysfs_write_attr_quiet(ctx, path, mode);
>>      if (rc) {
>>              /* check if something raced us to offline (unlikely) */
>> -- 
>> 2.34.1
>>
>>
> 


Reply via email to