* [PATCH v2 0/3] use bin_attribute to avoid buff overflow
@ 2021-06-02 13:48 Tian Tao
2021-06-02 13:48 ` [PATCH v2 1/3] lib: bitmap: introduce bitmap_print_to_buf Tian Tao
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Tian Tao @ 2021-06-02 13:48 UTC (permalink / raw)
To: gregkh, rafael, andriy.shevchenko, akpm
Cc: jonathan.cameron, song.bao.hua, linux-kernel, Tian Tao
patch #1 adds a new function cpumap_print_to_buf and patch #2 uses
this function in drivers/base/topology.c, and patch #3 uses this new
function in drivers/base/node.c.
v2:
split the original patch #1 into two patches and use kasprintf() in
patch #1 to simplify the code. do some minor formatting adjustments.
Tian Tao (3):
lib: bitmap: introduce bitmap_print_to_buf
topology: use bin_attribute to avoid buff overflow
drivers/base/node.c: use bin_attribute to avoid buff overflow
drivers/base/node.c | 52 ++++++++++++++--------
drivers/base/topology.c | 115 ++++++++++++++++++++++++++----------------------
include/linux/bitmap.h | 3 ++
include/linux/cpumask.h | 21 +++++++++
lib/bitmap.c | 38 +++++++++++++++-
5 files changed, 157 insertions(+), 72 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/3] lib: bitmap: introduce bitmap_print_to_buf
2021-06-02 13:48 [PATCH v2 0/3] use bin_attribute to avoid buff overflow Tian Tao
@ 2021-06-02 13:48 ` Tian Tao
2021-06-02 14:22 ` Jonathan Cameron
2021-06-02 15:47 ` Andy Shevchenko
2021-06-02 13:48 ` [PATCH v2 2/3] topology: use bin_attribute to avoid buff overflow Tian Tao
` (2 subsequent siblings)
3 siblings, 2 replies; 9+ messages in thread
From: Tian Tao @ 2021-06-02 13:48 UTC (permalink / raw)
To: gregkh, rafael, andriy.shevchenko, akpm
Cc: jonathan.cameron, song.bao.hua, linux-kernel, Tian Tao
New API bitmap_print_to_buf() with bin_attribute to avoid maskp
exceeding PAGE_SIZE. bitmap_print_to_pagebuf() is a special case
of bitmap_print_to_buf(), so in bitmap_print_to_pagebuf() call
bitmap_print_to_buf().
Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
---
include/linux/bitmap.h | 3 +++
include/linux/cpumask.h | 21 +++++++++++++++++++++
lib/bitmap.c | 38 ++++++++++++++++++++++++++++++++++++--
3 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 70a9324..bc401bd9b 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -219,6 +219,9 @@ extern unsigned int bitmap_ord_to_pos(const unsigned long *bitmap, unsigned int
extern int bitmap_print_to_pagebuf(bool list, char *buf,
const unsigned long *maskp, int nmaskbits);
+extern int bitmap_print_to_buf(bool list, char *buf,
+ const unsigned long *maskp, int nmaskbits, loff_t off, size_t count);
+
#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
#define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 383684e..56852f2 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -928,6 +928,27 @@ cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask)
nr_cpu_ids);
}
+/**
+ * cpumap_print_to_buf - copies the cpumask into the buffer either
+ * as comma-separated list of cpus or hex values of cpumask
+ * @list: indicates whether the cpumap must be list
+ * @mask: the cpumask to copy
+ * @buf: the buffer to copy into
+ * @off: in the string from which we are copying, We copy to @buf + off
+ * @count: the maximum number of bytes to print
+ *
+ * The role of cpumap_print_to_buf and cpumap_print_to_pagebuf is
+ * the same, the difference is that buf of bitmap_print_to_buf
+ * can be more than one pagesize.
+ */
+static inline ssize_t
+cpumap_print_to_buf(bool list, char *buf, const struct cpumask *mask,
+ loff_t off, size_t count)
+{
+ return bitmap_print_to_buf(list, buf, cpumask_bits(mask),
+ nr_cpu_ids, off, count);
+}
+
#if NR_CPUS <= BITS_PER_LONG
#define CPU_MASK_ALL \
(cpumask_t) { { \
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 75006c4..cb64e66 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -460,6 +460,40 @@ int bitmap_parse_user(const char __user *ubuf,
EXPORT_SYMBOL(bitmap_parse_user);
/**
+ * bitmap_print_to_buf - convert bitmap to list or hex format ASCII string
+ * @list: indicates whether the bitmap must be list
+ * @buf: the kernel space buffer to read to
+ * @maskp: pointer to bitmap to convert
+ * @nmaskbits: size of bitmap, in bits
+ * @off: offset in data buffer below
+ * @count: the maximum number of bytes to print
+ *
+ * The role of bitmap_print_to_buf and bitmap_print_to_pagebuf() is
+ * the same, the difference is that buf of bitmap_print_to_buf()
+ * can be more than one pagesize.
+ */
+int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp,
+ int nmaskbits, loff_t off, size_t count)
+{
+ int size;
+ void *data;
+ const char *fmt = list ? "%*pbl\n" : "%*pb\n";
+
+ if (off == LLONG_MAX && count == PAGE_SIZE - offset_in_page(buf))
+ return scnprintf(buf, count, fmt, nmaskbits, maskp);
+
+ data = kasprintf(GFP_KERNEL, fmt, nmaskbits, maskp);
+ if (!data)
+ return -ENOMEM;
+
+ size = memory_read_from_buffer(buf, count, &off, data, strlen(data));
+ kfree(data);
+
+ return size;
+}
+EXPORT_SYMBOL(bitmap_print_to_buf);
+
+/**
* bitmap_print_to_pagebuf - convert bitmap to list or hex format ASCII string
* @list: indicates whether the bitmap must be list
* @buf: page aligned buffer into which string is placed
@@ -480,8 +514,8 @@ int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp,
{
ptrdiff_t len = PAGE_SIZE - offset_in_page(buf);
- return list ? scnprintf(buf, len, "%*pbl\n", nmaskbits, maskp) :
- scnprintf(buf, len, "%*pb\n", nmaskbits, maskp);
+ return bitmap_print_to_buf(list, buf, maskp, nmaskbits,
+ LLONG_MAX, len);
}
EXPORT_SYMBOL(bitmap_print_to_pagebuf);
--
2.7.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/3] topology: use bin_attribute to avoid buff overflow
2021-06-02 13:48 [PATCH v2 0/3] use bin_attribute to avoid buff overflow Tian Tao
2021-06-02 13:48 ` [PATCH v2 1/3] lib: bitmap: introduce bitmap_print_to_buf Tian Tao
@ 2021-06-02 13:48 ` Tian Tao
2021-06-02 15:48 ` Andy Shevchenko
2021-06-02 13:48 ` [PATCH v2 3/3] drivers/base/node.c: " Tian Tao
2021-06-02 15:42 ` [PATCH v2 0/3] " Andy Shevchenko
3 siblings, 1 reply; 9+ messages in thread
From: Tian Tao @ 2021-06-02 13:48 UTC (permalink / raw)
To: gregkh, rafael, andriy.shevchenko, akpm
Cc: jonathan.cameron, song.bao.hua, linux-kernel, Tian Tao
Reading sys/devices/system/cpu/cpuX/topology/ returns cpu topology.
However, the size of this file is limited to PAGE_SIZE because of the
limitation for sysfs attribute. so we use bin_attribute instead of
attribute to avoid NR_CPUS too big to cause buff overflow.
This patch is based on the following discussion.
https://lore.kernel.org/lkml/20210319041618.14316-2-song.bao.hua@hisilicon.com/
Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
---
drivers/base/topology.c | 115 ++++++++++++++++++++++++++----------------------
1 file changed, 63 insertions(+), 52 deletions(-)
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index 4d254fc..013edbb 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -21,25 +21,27 @@ static ssize_t name##_show(struct device *dev, \
return sysfs_emit(buf, "%d\n", topology_##name(dev->id)); \
}
-#define define_siblings_show_map(name, mask) \
-static ssize_t name##_show(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- return cpumap_print_to_pagebuf(false, buf, topology_##mask(dev->id));\
+#define define_siblings_read_func(name, mask) \
+static ssize_t name##_read(struct file *file, struct kobject *kobj, \
+ struct bin_attribute *attr, char *buf, \
+ loff_t off, size_t count) \
+{ \
+ struct device *dev = kobj_to_dev(kobj); \
+ \
+ return cpumap_print_to_buf(false, buf, topology_##mask(dev->id), \
+ off, count); \
+} \
+ \
+static ssize_t name##_list_read(struct file *file, struct kobject *kobj, \
+ struct bin_attribute *attr, char *buf, \
+ loff_t off, size_t count) \
+{ \
+ struct device *dev = kobj_to_dev(kobj); \
+ \
+ return cpumap_print_to_buf(true, buf, topology_##mask(dev->id), \
+ off, count); \
}
-#define define_siblings_show_list(name, mask) \
-static ssize_t name##_list_show(struct device *dev, \
- struct device_attribute *attr, \
- char *buf) \
-{ \
- return cpumap_print_to_pagebuf(true, buf, topology_##mask(dev->id));\
-}
-
-#define define_siblings_show_func(name, mask) \
- define_siblings_show_map(name, mask); \
- define_siblings_show_list(name, mask)
-
define_id_show_func(physical_package_id);
static DEVICE_ATTR_RO(physical_package_id);
@@ -49,71 +51,80 @@ static DEVICE_ATTR_RO(die_id);
define_id_show_func(core_id);
static DEVICE_ATTR_RO(core_id);
-define_siblings_show_func(thread_siblings, sibling_cpumask);
-static DEVICE_ATTR_RO(thread_siblings);
-static DEVICE_ATTR_RO(thread_siblings_list);
+define_siblings_read_func(thread_siblings, sibling_cpumask);
+static BIN_ATTR_RO(thread_siblings, 0);
+static BIN_ATTR_RO(thread_siblings_list, 0);
-define_siblings_show_func(core_cpus, sibling_cpumask);
-static DEVICE_ATTR_RO(core_cpus);
-static DEVICE_ATTR_RO(core_cpus_list);
+define_siblings_read_func(core_cpus, sibling_cpumask);
+static BIN_ATTR_RO(core_cpus, 0);
+static BIN_ATTR_RO(core_cpus_list, 0);
-define_siblings_show_func(core_siblings, core_cpumask);
-static DEVICE_ATTR_RO(core_siblings);
-static DEVICE_ATTR_RO(core_siblings_list);
+define_siblings_read_func(core_siblings, core_cpumask);
+static BIN_ATTR_RO(core_siblings, 0);
+static BIN_ATTR_RO(core_siblings_list, 0);
-define_siblings_show_func(die_cpus, die_cpumask);
-static DEVICE_ATTR_RO(die_cpus);
-static DEVICE_ATTR_RO(die_cpus_list);
+define_siblings_read_func(die_cpus, die_cpumask);
+static BIN_ATTR_RO(die_cpus, 0);
+static BIN_ATTR_RO(die_cpus_list, 0);
-define_siblings_show_func(package_cpus, core_cpumask);
-static DEVICE_ATTR_RO(package_cpus);
-static DEVICE_ATTR_RO(package_cpus_list);
+define_siblings_read_func(package_cpus, core_cpumask);
+static BIN_ATTR_RO(package_cpus, 0);
+static BIN_ATTR_RO(package_cpus_list, 0);
#ifdef CONFIG_SCHED_BOOK
define_id_show_func(book_id);
static DEVICE_ATTR_RO(book_id);
-define_siblings_show_func(book_siblings, book_cpumask);
-static DEVICE_ATTR_RO(book_siblings);
-static DEVICE_ATTR_RO(book_siblings_list);
+define_siblings_read_func(book_siblings, book_cpumask);
+static BIN_ATTR_RO(book_siblings, 0);
+static BIN_ATTR_RO(book_siblings_list, 0);
#endif
#ifdef CONFIG_SCHED_DRAWER
define_id_show_func(drawer_id);
static DEVICE_ATTR_RO(drawer_id);
-define_siblings_show_func(drawer_siblings, drawer_cpumask);
-static DEVICE_ATTR_RO(drawer_siblings);
-static DEVICE_ATTR_RO(drawer_siblings_list);
+define_siblings_read_func(drawer_siblings, drawer_cpumask);
+static BIN_ATTR_RO(drawer_siblings, 0);
+static BIN_ATTR_RO(drawer_siblings_list, 0);
#endif
+static struct bin_attribute *bin_attrs[] = {
+ &bin_attr_core_cpus,
+ &bin_attr_core_cpus_list,
+ &bin_attr_thread_siblings,
+ &bin_attr_thread_siblings_list,
+ &bin_attr_core_siblings,
+ &bin_attr_core_siblings_list,
+ &bin_attr_die_cpus,
+ &bin_attr_die_cpus_list,
+ &bin_attr_package_cpus,
+ &bin_attr_package_cpus_list,
+#ifdef CONFIG_SCHED_BOOK
+ &bin_attr_book_siblings,
+ &bin_attr_book_siblings_list,
+#endif
+#ifdef CONFIG_SCHED_DRAWER
+ &bin_attr_drawer_siblings,
+ &bin_attr_drawer_siblings_list,
+#endif
+ NULL,
+};
+
static struct attribute *default_attrs[] = {
&dev_attr_physical_package_id.attr,
&dev_attr_die_id.attr,
&dev_attr_core_id.attr,
- &dev_attr_thread_siblings.attr,
- &dev_attr_thread_siblings_list.attr,
- &dev_attr_core_cpus.attr,
- &dev_attr_core_cpus_list.attr,
- &dev_attr_core_siblings.attr,
- &dev_attr_core_siblings_list.attr,
- &dev_attr_die_cpus.attr,
- &dev_attr_die_cpus_list.attr,
- &dev_attr_package_cpus.attr,
- &dev_attr_package_cpus_list.attr,
#ifdef CONFIG_SCHED_BOOK
&dev_attr_book_id.attr,
- &dev_attr_book_siblings.attr,
- &dev_attr_book_siblings_list.attr,
#endif
#ifdef CONFIG_SCHED_DRAWER
&dev_attr_drawer_id.attr,
- &dev_attr_drawer_siblings.attr,
- &dev_attr_drawer_siblings_list.attr,
#endif
NULL
};
static const struct attribute_group topology_attr_group = {
.attrs = default_attrs,
+ .bin_attrs = bin_attrs,
.name = "topology"
};
--
2.7.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/3] drivers/base/node.c: use bin_attribute to avoid buff overflow
2021-06-02 13:48 [PATCH v2 0/3] use bin_attribute to avoid buff overflow Tian Tao
2021-06-02 13:48 ` [PATCH v2 1/3] lib: bitmap: introduce bitmap_print_to_buf Tian Tao
2021-06-02 13:48 ` [PATCH v2 2/3] topology: use bin_attribute to avoid buff overflow Tian Tao
@ 2021-06-02 13:48 ` Tian Tao
2021-06-02 15:50 ` Andy Shevchenko
2021-06-02 15:42 ` [PATCH v2 0/3] " Andy Shevchenko
3 siblings, 1 reply; 9+ messages in thread
From: Tian Tao @ 2021-06-02 13:48 UTC (permalink / raw)
To: gregkh, rafael, andriy.shevchenko, akpm
Cc: jonathan.cameron, song.bao.hua, linux-kernel, Tian Tao
Reading sys/devices/system/cpu/cpuX/nodeX/ returns cpumap and cpulist.
However, the size of this file is limited to PAGE_SIZE because of the
limitation for sysfs attribute. so we use bin_attribute instead of
attribute to avoid NR_CPUS too big to cause buff overflow.
Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
---
drivers/base/node.c | 52 ++++++++++++++++++++++++++++++++++------------------
1 file changed, 34 insertions(+), 18 deletions(-)
diff --git a/drivers/base/node.c b/drivers/base/node.c
index f449dbb..2659bb44 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -27,42 +27,45 @@ static struct bus_type node_subsys = {
};
-static ssize_t node_read_cpumap(struct device *dev, bool list, char *buf)
+static ssize_t node_read_cpumap(struct device *dev, bool list,
+ char *buf, loff_t off, size_t count)
{
ssize_t n;
cpumask_var_t mask;
struct node *node_dev = to_node(dev);
- /* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */
- BUILD_BUG_ON((NR_CPUS/32 * 9) > (PAGE_SIZE-1));
-
if (!alloc_cpumask_var(&mask, GFP_KERNEL))
return 0;
cpumask_and(mask, cpumask_of_node(node_dev->dev.id), cpu_online_mask);
- n = cpumap_print_to_pagebuf(list, buf, mask);
+ n = cpumap_print_to_buf(list, buf, mask, off, count);
free_cpumask_var(mask);
return n;
}
-static inline ssize_t cpumap_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static inline ssize_t cpumap_read(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
{
- return node_read_cpumap(dev, false, buf);
+ struct device *dev = kobj_to_dev(kobj);
+
+ return node_read_cpumap(dev, false, buf, off, count);
}
-static DEVICE_ATTR_RO(cpumap);
-static inline ssize_t cpulist_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static BIN_ATTR_RO(cpumap, 0);
+
+static inline ssize_t cpulist_read(struct file *file, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
{
- return node_read_cpumap(dev, true, buf);
+ struct device *dev = kobj_to_dev(kobj);
+
+ return node_read_cpumap(dev, true, buf, off, count);
}
-static DEVICE_ATTR_RO(cpulist);
+static BIN_ATTR_RO(cpulist, 0);
/**
* struct node_access_nodes - Access class device to hold user visible
@@ -557,15 +560,28 @@ static ssize_t node_read_distance(struct device *dev,
static DEVICE_ATTR(distance, 0444, node_read_distance, NULL);
static struct attribute *node_dev_attrs[] = {
- &dev_attr_cpumap.attr,
- &dev_attr_cpulist.attr,
&dev_attr_meminfo.attr,
&dev_attr_numastat.attr,
&dev_attr_distance.attr,
&dev_attr_vmstat.attr,
NULL
};
-ATTRIBUTE_GROUPS(node_dev);
+
+static struct bin_attribute *node_dev_bin_attrs[] = {
+ &bin_attr_cpumap,
+ &bin_attr_cpulist,
+ NULL,
+};
+
+static const struct attribute_group node_dev_group = {
+ .attrs = node_dev_attrs,
+ .bin_attrs = node_dev_bin_attrs
+};
+
+static const struct attribute_group *node_dev_groups[] = {
+ &node_dev_group,
+ NULL,
+};
#ifdef CONFIG_HUGETLBFS
/*
--
2.7.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/3] lib: bitmap: introduce bitmap_print_to_buf
2021-06-02 13:48 ` [PATCH v2 1/3] lib: bitmap: introduce bitmap_print_to_buf Tian Tao
@ 2021-06-02 14:22 ` Jonathan Cameron
2021-06-02 15:47 ` Andy Shevchenko
1 sibling, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2021-06-02 14:22 UTC (permalink / raw)
To: Tian Tao
Cc: gregkh, rafael, andriy.shevchenko, akpm, song.bao.hua, linux-kernel
On Wed, 2 Jun 2021 21:48:52 +0800
Tian Tao <tiantao6@hisilicon.com> wrote:
> New API bitmap_print_to_buf() with bin_attribute to avoid maskp
> exceeding PAGE_SIZE. bitmap_print_to_pagebuf() is a special case
> of bitmap_print_to_buf(), so in bitmap_print_to_pagebuf() call
> bitmap_print_to_buf().
>
> Signed-off-by: Tian Tao <tiantao6@hisilicon.com>
Hi,
I think you need strlen() + 1 as strlen() doesn't include the null terminator.
Also good to add () in a few more places to make the hyperlinks work in the
html docs (fairly sure it needs those)
I don't really like the fact we can't get the string length without that
extra call (as it's buried in the kasprintf() implementation) but this is
unlikely to be a high performance path so clean code is better.
Otherwise, LGTM
> ---
> include/linux/bitmap.h | 3 +++
> include/linux/cpumask.h | 21 +++++++++++++++++++++
> lib/bitmap.c | 38 ++++++++++++++++++++++++++++++++++++--
> 3 files changed, 60 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
> index 70a9324..bc401bd9b 100644
> --- a/include/linux/bitmap.h
> +++ b/include/linux/bitmap.h
> @@ -219,6 +219,9 @@ extern unsigned int bitmap_ord_to_pos(const unsigned long *bitmap, unsigned int
> extern int bitmap_print_to_pagebuf(bool list, char *buf,
> const unsigned long *maskp, int nmaskbits);
>
> +extern int bitmap_print_to_buf(bool list, char *buf,
> + const unsigned long *maskp, int nmaskbits, loff_t off, size_t count);
> +
> #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
> #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
>
> diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
> index 383684e..56852f2 100644
> --- a/include/linux/cpumask.h
> +++ b/include/linux/cpumask.h
> @@ -928,6 +928,27 @@ cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask)
> nr_cpu_ids);
> }
>
> +/**
> + * cpumap_print_to_buf - copies the cpumask into the buffer either
> + * as comma-separated list of cpus or hex values of cpumask
> + * @list: indicates whether the cpumap must be list
> + * @mask: the cpumask to copy
> + * @buf: the buffer to copy into
> + * @off: in the string from which we are copying, We copy to @buf + off
> + * @count: the maximum number of bytes to print
> + *
> + * The role of cpumap_print_to_buf and cpumap_print_to_pagebuf is
cpumap_print_to_buf()
+ other cases of the same so that hyperlinks work in the html docs.
> + * the same, the difference is that buf of bitmap_print_to_buf
> + * can be more than one pagesize.
> + */
> +static inline ssize_t
> +cpumap_print_to_buf(bool list, char *buf, const struct cpumask *mask,
> + loff_t off, size_t count)
> +{
> + return bitmap_print_to_buf(list, buf, cpumask_bits(mask),
> + nr_cpu_ids, off, count);
> +}
> +
> #if NR_CPUS <= BITS_PER_LONG
> #define CPU_MASK_ALL \
> (cpumask_t) { { \
> diff --git a/lib/bitmap.c b/lib/bitmap.c
> index 75006c4..cb64e66 100644
> --- a/lib/bitmap.c
> +++ b/lib/bitmap.c
> @@ -460,6 +460,40 @@ int bitmap_parse_user(const char __user *ubuf,
> EXPORT_SYMBOL(bitmap_parse_user);
>
> /**
> + * bitmap_print_to_buf - convert bitmap to list or hex format ASCII string
> + * @list: indicates whether the bitmap must be list
> + * @buf: the kernel space buffer to read to
> + * @maskp: pointer to bitmap to convert
> + * @nmaskbits: size of bitmap, in bits
> + * @off: offset in data buffer below
> + * @count: the maximum number of bytes to print
> + *
> + * The role of bitmap_print_to_buf and bitmap_print_to_pagebuf() is
> + * the same, the difference is that buf of bitmap_print_to_buf()
> + * can be more than one pagesize.
> + */
> +int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp,
> + int nmaskbits, loff_t off, size_t count)
> +{
> + int size;
> + void *data;
> + const char *fmt = list ? "%*pbl\n" : "%*pb\n";
> +
> + if (off == LLONG_MAX && count == PAGE_SIZE - offset_in_page(buf))
> + return scnprintf(buf, count, fmt, nmaskbits, maskp);
> +
> + data = kasprintf(GFP_KERNEL, fmt, nmaskbits, maskp);
> + if (!data)
> + return -ENOMEM;
> +
> + size = memory_read_from_buffer(buf, count, &off, data, strlen(data));
strlen(data) + 1 I think...
> + kfree(data);
> +
> + return size;
> +}
> +EXPORT_SYMBOL(bitmap_print_to_buf);
> +
> +/**
> * bitmap_print_to_pagebuf - convert bitmap to list or hex format ASCII string
> * @list: indicates whether the bitmap must be list
> * @buf: page aligned buffer into which string is placed
> @@ -480,8 +514,8 @@ int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp,
> {
> ptrdiff_t len = PAGE_SIZE - offset_in_page(buf);
>
> - return list ? scnprintf(buf, len, "%*pbl\n", nmaskbits, maskp) :
> - scnprintf(buf, len, "%*pb\n", nmaskbits, maskp);
> + return bitmap_print_to_buf(list, buf, maskp, nmaskbits,
> + LLONG_MAX, len);
> }
> EXPORT_SYMBOL(bitmap_print_to_pagebuf);
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/3] use bin_attribute to avoid buff overflow
2021-06-02 13:48 [PATCH v2 0/3] use bin_attribute to avoid buff overflow Tian Tao
` (2 preceding siblings ...)
2021-06-02 13:48 ` [PATCH v2 3/3] drivers/base/node.c: " Tian Tao
@ 2021-06-02 15:42 ` Andy Shevchenko
3 siblings, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2021-06-02 15:42 UTC (permalink / raw)
To: Tian Tao
Cc: gregkh, rafael, akpm, jonathan.cameron, song.bao.hua, linux-kernel
On Wed, Jun 02, 2021 at 09:48:51PM +0800, Tian Tao wrote:
> patch #1 adds a new function cpumap_print_to_buf and patch #2 uses
> this function in drivers/base/topology.c, and patch #3 uses this new
> function in drivers/base/node.c.
Somehow you missed to include BITMAP maintainers / reviewers.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/3] lib: bitmap: introduce bitmap_print_to_buf
2021-06-02 13:48 ` [PATCH v2 1/3] lib: bitmap: introduce bitmap_print_to_buf Tian Tao
2021-06-02 14:22 ` Jonathan Cameron
@ 2021-06-02 15:47 ` Andy Shevchenko
1 sibling, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2021-06-02 15:47 UTC (permalink / raw)
To: Tian Tao
Cc: gregkh, rafael, akpm, jonathan.cameron, song.bao.hua, linux-kernel
On Wed, Jun 02, 2021 at 09:48:52PM +0800, Tian Tao wrote:
> New API bitmap_print_to_buf() with bin_attribute to avoid maskp
> exceeding PAGE_SIZE. bitmap_print_to_pagebuf() is a special case
> of bitmap_print_to_buf(), so in bitmap_print_to_pagebuf() call
> bitmap_print_to_buf().
...
> + * The role of cpumap_print_to_buf and cpumap_print_to_pagebuf is
* The role of cpumap_print_to_buf() and cpumap_print_to_pagebuf() is
...
> + * The role of bitmap_print_to_buf and bitmap_print_to_pagebuf() is
* The role of bitmap_print_to_buf() and bitmap_print_to_pagebuf() is
...
> + int size;
Strictly speaking it should be ssize_t.
> + void *data;
> + const char *fmt = list ? "%*pbl\n" : "%*pb\n";
Can you use reversed xmas tree order?
...
> + return bitmap_print_to_buf(list, buf, maskp, nmaskbits,
> + LLONG_MAX, len);
It fits one line.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/3] topology: use bin_attribute to avoid buff overflow
2021-06-02 13:48 ` [PATCH v2 2/3] topology: use bin_attribute to avoid buff overflow Tian Tao
@ 2021-06-02 15:48 ` Andy Shevchenko
0 siblings, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2021-06-02 15:48 UTC (permalink / raw)
To: Tian Tao
Cc: gregkh, rafael, akpm, jonathan.cameron, song.bao.hua, linux-kernel
On Wed, Jun 02, 2021 at 09:48:53PM +0800, Tian Tao wrote:
> Reading sys/devices/system/cpu/cpuX/topology/ returns cpu topology.
> However, the size of this file is limited to PAGE_SIZE because of the
> limitation for sysfs attribute. so we use bin_attribute instead of
> attribute to avoid NR_CPUS too big to cause buff overflow.
> This patch is based on the following discussion.
> https://lore.kernel.org/lkml/20210319041618.14316-2-song.bao.hua@hisilicon.com/
Link: tag?
...
> +static struct bin_attribute *bin_attrs[] = {
> + &bin_attr_core_cpus,
> + &bin_attr_core_cpus_list,
> + &bin_attr_thread_siblings,
> + &bin_attr_thread_siblings_list,
> + &bin_attr_core_siblings,
> + &bin_attr_core_siblings_list,
> + &bin_attr_die_cpus,
> + &bin_attr_die_cpus_list,
> + &bin_attr_package_cpus,
> + &bin_attr_package_cpus_list,
> +#ifdef CONFIG_SCHED_BOOK
> + &bin_attr_book_siblings,
> + &bin_attr_book_siblings_list,
> +#endif
> +#ifdef CONFIG_SCHED_DRAWER
> + &bin_attr_drawer_siblings,
> + &bin_attr_drawer_siblings_list,
> +#endif
> + NULL,
No comma for terminator line.
> +};
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/3] drivers/base/node.c: use bin_attribute to avoid buff overflow
2021-06-02 13:48 ` [PATCH v2 3/3] drivers/base/node.c: " Tian Tao
@ 2021-06-02 15:50 ` Andy Shevchenko
0 siblings, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2021-06-02 15:50 UTC (permalink / raw)
To: Tian Tao
Cc: gregkh, rafael, akpm, jonathan.cameron, song.bao.hua, linux-kernel
On Wed, Jun 02, 2021 at 09:48:54PM +0800, Tian Tao wrote:
> Reading sys/devices/system/cpu/cpuX/nodeX/ returns cpumap and cpulist.
> However, the size of this file is limited to PAGE_SIZE because of the
> limitation for sysfs attribute. so we use bin_attribute instead of
> attribute to avoid NR_CPUS too big to cause buff overflow.
...
> -static ssize_t node_read_cpumap(struct device *dev, bool list, char *buf)
> +static ssize_t node_read_cpumap(struct device *dev, bool list,
> + char *buf, loff_t off, size_t count)
Why you moved char *buf to the next line? Replacing ) by , doesn't change
character count. Perhaps you need to reconfigure your editor.
...
> +static struct bin_attribute *node_dev_bin_attrs[] = {
> + &bin_attr_cpumap,
> + &bin_attr_cpulist,
> + NULL,
No comma.
> +};
...
> +static const struct attribute_group *node_dev_groups[] = {
> + &node_dev_group,
> + NULL,
Ditto.
> +};
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2021-06-02 15:50 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-02 13:48 [PATCH v2 0/3] use bin_attribute to avoid buff overflow Tian Tao
2021-06-02 13:48 ` [PATCH v2 1/3] lib: bitmap: introduce bitmap_print_to_buf Tian Tao
2021-06-02 14:22 ` Jonathan Cameron
2021-06-02 15:47 ` Andy Shevchenko
2021-06-02 13:48 ` [PATCH v2 2/3] topology: use bin_attribute to avoid buff overflow Tian Tao
2021-06-02 15:48 ` Andy Shevchenko
2021-06-02 13:48 ` [PATCH v2 3/3] drivers/base/node.c: " Tian Tao
2021-06-02 15:50 ` Andy Shevchenko
2021-06-02 15:42 ` [PATCH v2 0/3] " Andy Shevchenko
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.