Re: [PATCHv8 06/10] node: Add memory-side caching attributes

2019-03-13 Thread Rafael J. Wysocki
On Mon, Mar 11, 2019 at 9:55 PM Keith Busch  wrote:
>
> System memory may have caches to help improve access speed to frequently
> requested address ranges. While the system provided cache is transparent
> to the software accessing these memory ranges, applications can optimize
> their own access based on cache attributes.
>
> Provide a new API for the kernel to register these memory-side caches
> under the memory node that provides it.
>
> The new sysfs representation is modeled from the existing cpu cacheinfo
> attributes, as seen from /sys/devices/system/cpu//cache/.  Unlike CPU
> cacheinfo though, the node cache level is reported from the view of the
> memory. A higher level number is nearer to the CPU, while lower levels
> are closer to the last level memory.
>
> The exported attributes are the cache size, the line size, associativity
> indexing, and write back policy, and add the attributes for the system
> memory caches to sysfs stable documentation.
>
> Signed-off-by: Keith Busch 

Reviewed-by: Rafael J. Wysocki 

> ---
>  Documentation/ABI/stable/sysfs-devices-node |  34 +++
>  drivers/base/node.c | 151 
> 
>  include/linux/node.h|  39 +++
>  3 files changed, 224 insertions(+)
>
> diff --git a/Documentation/ABI/stable/sysfs-devices-node 
> b/Documentation/ABI/stable/sysfs-devices-node
> index 735a40a3f9b2..f7ce68fbd4b9 100644
> --- a/Documentation/ABI/stable/sysfs-devices-node
> +++ b/Documentation/ABI/stable/sysfs-devices-node
> @@ -142,3 +142,37 @@ Contact:   Keith Busch 
>  Description:
> This node's write latency in nanoseconds when access
> from nodes found in this class's linked initiators.
> +
> +What:  /sys/devices/system/node/nodeX/memory_side_cache/indexY/
> +Date:  December 2018
> +Contact:   Keith Busch 
> +Description:
> +   The directory containing attributes for the memory-side cache
> +   level 'Y'.
> +
> +What:  
> /sys/devices/system/node/nodeX/memory_side_cache/indexY/indexing
> +Date:  December 2018
> +Contact:   Keith Busch 
> +Description:
> +   The caches associativity indexing: 0 for direct mapped,
> +   non-zero if indexed.
> +
> +What:  
> /sys/devices/system/node/nodeX/memory_side_cache/indexY/line_size
> +Date:  December 2018
> +Contact:   Keith Busch 
> +Description:
> +   The number of bytes accessed from the next cache level on a
> +   cache miss.
> +
> +What:  /sys/devices/system/node/nodeX/memory_side_cache/indexY/size
> +Date:  December 2018
> +Contact:   Keith Busch 
> +Description:
> +   The size of this memory side cache in bytes.
> +
> +What:  
> /sys/devices/system/node/nodeX/memory_side_cache/indexY/write_policy
> +Date:  December 2018
> +Contact:   Keith Busch 
> +Description:
> +   The cache write policy: 0 for write-back, 1 for write-through,
> +   other or unknown.
> diff --git a/drivers/base/node.c b/drivers/base/node.c
> index 2de546a040a5..8598fcbd2a17 100644
> --- a/drivers/base/node.c
> +++ b/drivers/base/node.c
> @@ -205,6 +205,155 @@ void node_set_perf_attrs(unsigned int nid, struct 
> node_hmem_attrs *hmem_attrs,
> }
> }
>  }
> +
> +/**
> + * struct node_cache_info - Internal tracking for memory node caches
> + * @dev:   Device represeting the cache level
> + * @node:  List element for tracking in the node
> + * @cache_attrs:Attributes for this cache level
> + */
> +struct node_cache_info {
> +   struct device dev;
> +   struct list_head node;
> +   struct node_cache_attrs cache_attrs;
> +};
> +#define to_cache_info(device) container_of(device, struct node_cache_info, 
> dev)
> +
> +#define CACHE_ATTR(name, fmt)  \
> +static ssize_t name##_show(struct device *dev, \
> +  struct device_attribute *attr,   \
> +  char *buf)   \
> +{  \
> +   return sprintf(buf, fmt "\n", to_cache_info(dev)->cache_attrs.name);\
> +}  \
> +DEVICE_ATTR_RO(name);
> +
> +CACHE_ATTR(size, "%llu")
> +CACHE_ATTR(line_size, "%u")
> +CACHE_ATTR(indexing, "%u")
> +CACHE_ATTR(write_policy, "%u")
> +
> +static struct attribute *cache_attrs[] = {
> +   _attr_indexing.attr,
> +   _attr_size.attr,
> +   _attr_line_size.attr,
> +   _attr_write_policy.attr,
> +   NULL,
> +};
> +ATTRIBUTE_GROUPS(cache);
> +
> +static void node_cache_release(struct device *dev)
> +{
> +   kfree(dev);
> +}
> +
> +static void node_cacheinfo_release(struct device *dev)
> +{
> +   struct node_cache_info *info = 

[PATCHv8 06/10] node: Add memory-side caching attributes

2019-03-11 Thread Keith Busch
System memory may have caches to help improve access speed to frequently
requested address ranges. While the system provided cache is transparent
to the software accessing these memory ranges, applications can optimize
their own access based on cache attributes.

Provide a new API for the kernel to register these memory-side caches
under the memory node that provides it.

The new sysfs representation is modeled from the existing cpu cacheinfo
attributes, as seen from /sys/devices/system/cpu//cache/.  Unlike CPU
cacheinfo though, the node cache level is reported from the view of the
memory. A higher level number is nearer to the CPU, while lower levels
are closer to the last level memory.

The exported attributes are the cache size, the line size, associativity
indexing, and write back policy, and add the attributes for the system
memory caches to sysfs stable documentation.

Signed-off-by: Keith Busch 
---
 Documentation/ABI/stable/sysfs-devices-node |  34 +++
 drivers/base/node.c | 151 
 include/linux/node.h|  39 +++
 3 files changed, 224 insertions(+)

diff --git a/Documentation/ABI/stable/sysfs-devices-node 
b/Documentation/ABI/stable/sysfs-devices-node
index 735a40a3f9b2..f7ce68fbd4b9 100644
--- a/Documentation/ABI/stable/sysfs-devices-node
+++ b/Documentation/ABI/stable/sysfs-devices-node
@@ -142,3 +142,37 @@ Contact:   Keith Busch 
 Description:
This node's write latency in nanoseconds when access
from nodes found in this class's linked initiators.
+
+What:  /sys/devices/system/node/nodeX/memory_side_cache/indexY/
+Date:  December 2018
+Contact:   Keith Busch 
+Description:
+   The directory containing attributes for the memory-side cache
+   level 'Y'.
+
+What:  /sys/devices/system/node/nodeX/memory_side_cache/indexY/indexing
+Date:  December 2018
+Contact:   Keith Busch 
+Description:
+   The caches associativity indexing: 0 for direct mapped,
+   non-zero if indexed.
+
+What:  
/sys/devices/system/node/nodeX/memory_side_cache/indexY/line_size
+Date:  December 2018
+Contact:   Keith Busch 
+Description:
+   The number of bytes accessed from the next cache level on a
+   cache miss.
+
+What:  /sys/devices/system/node/nodeX/memory_side_cache/indexY/size
+Date:  December 2018
+Contact:   Keith Busch 
+Description:
+   The size of this memory side cache in bytes.
+
+What:  
/sys/devices/system/node/nodeX/memory_side_cache/indexY/write_policy
+Date:  December 2018
+Contact:   Keith Busch 
+Description:
+   The cache write policy: 0 for write-back, 1 for write-through,
+   other or unknown.
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 2de546a040a5..8598fcbd2a17 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -205,6 +205,155 @@ void node_set_perf_attrs(unsigned int nid, struct 
node_hmem_attrs *hmem_attrs,
}
}
 }
+
+/**
+ * struct node_cache_info - Internal tracking for memory node caches
+ * @dev:   Device represeting the cache level
+ * @node:  List element for tracking in the node
+ * @cache_attrs:Attributes for this cache level
+ */
+struct node_cache_info {
+   struct device dev;
+   struct list_head node;
+   struct node_cache_attrs cache_attrs;
+};
+#define to_cache_info(device) container_of(device, struct node_cache_info, dev)
+
+#define CACHE_ATTR(name, fmt)  \
+static ssize_t name##_show(struct device *dev, \
+  struct device_attribute *attr,   \
+  char *buf)   \
+{  \
+   return sprintf(buf, fmt "\n", to_cache_info(dev)->cache_attrs.name);\
+}  \
+DEVICE_ATTR_RO(name);
+
+CACHE_ATTR(size, "%llu")
+CACHE_ATTR(line_size, "%u")
+CACHE_ATTR(indexing, "%u")
+CACHE_ATTR(write_policy, "%u")
+
+static struct attribute *cache_attrs[] = {
+   _attr_indexing.attr,
+   _attr_size.attr,
+   _attr_line_size.attr,
+   _attr_write_policy.attr,
+   NULL,
+};
+ATTRIBUTE_GROUPS(cache);
+
+static void node_cache_release(struct device *dev)
+{
+   kfree(dev);
+}
+
+static void node_cacheinfo_release(struct device *dev)
+{
+   struct node_cache_info *info = to_cache_info(dev);
+   kfree(info);
+}
+
+static void node_init_cache_dev(struct node *node)
+{
+   struct device *dev;
+
+   dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+   if (!dev)
+   return;
+
+   dev->parent = >dev;
+   dev->release = node_cache_release;
+   if (dev_set_name(dev, "memory_side_cache"))
+