Messages in this thread | | | From | "Song Bao Hua (Barry Song)" <> | Subject | RE: [PATCH v8 1/5] cpumask: introduce cpumap_print_to_buf to support large bitmask and list | Date | Thu, 5 Aug 2021 23:05:59 +0000 |
| |
> -----Original Message----- > From: Greg KH [mailto:gregkh@linuxfoundation.org] > Sent: Friday, August 6, 2021 12:53 AM > To: Song Bao Hua (Barry Song) <song.bao.hua@hisilicon.com> > Cc: andriy.shevchenko@linux.intel.com; yury.norov@gmail.com; > linux-kernel@vger.kernel.org; akpm@linux-foundation.org; > dave.hansen@intel.com; linux@rasmusvillemoes.dk; rafael@kernel.org; > rdunlap@infradead.org; agordeev@linux.ibm.com; sbrivio@redhat.com; > jianpeng.ma@intel.com; valentin.schneider@arm.com; peterz@infradead.org; > bristot@redhat.com; guodong.xu@linaro.org; tangchengchang > <tangchengchang@huawei.com>; Zengtao (B) <prime.zeng@hisilicon.com>; > yangyicong <yangyicong@huawei.com>; tim.c.chen@linux.intel.com; Linuxarm > <linuxarm@huawei.com>; tiantao (H) <tiantao6@hisilicon.com>; Jonathan Cameron > <jonathan.cameron@huawei.com> > Subject: Re: [PATCH v8 1/5] cpumask: introduce cpumap_print_to_buf to support > large bitmask and list > > On Thu, Jul 29, 2021 at 05:42:04PM +1200, Barry Song wrote: > > From: Tian Tao <tiantao6@hisilicon.com> > > > > The existing cpumap_print_to_pagebuf() is used by cpu topology and other > > drivers to export hexadecimal bitmask and decimal list to userspace by > > sysfs ABI. > > > > Right now, those drivers are using a normal attribute for this kind of > > ABIs. A normal attribute typically has show entry as below: > > > > static ssize_t example_dev_show(struct device *dev, > > struct device_attribute *attr, char *buf) > > { > > ... > > return cpumap_print_to_pagebuf(true, buf, &pmu_mmdc->cpu); > > } > > show entry of attribute has no offset and count parameters and this > > means the file is limited to one page only. > > > > cpumap_print_to_pagebuf() API works terribly well for this kind of > > normal attribute with buf parameter and without offset, count: > > > > static inline ssize_t > > cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask) > > { > > return bitmap_print_to_pagebuf(list, buf, cpumask_bits(mask), > > nr_cpu_ids); > > } > > > > The problem is once we have many cpus, we have a chance to make bitmask > > or list more than one page. Especially for list, it could be as complex > > as 0,3,5,7,9,...... We have no simple way to know it exact size. > > > > It turns out bin_attribute is a way to break this limit. bin_attribute > > has show entry as below: > > static ssize_t > > example_bin_attribute_show(struct file *filp, struct kobject *kobj, > > struct bin_attribute *attr, char *buf, > > loff_t offset, size_t count) > > { > > ... > > } > > > > With the new offset and count parameters, this makes sysfs ABI be able > > to support file size more than one page. For example, offset could be > > >= 4096. > > > > This patch introduces cpumap_print_to_buf() and its bitmap infrastructure > > bitmap_print_to_buf() so that those drivers can move to bin_attribute to > > support large bitmask and list. At the same time, we have to pass those > > corresponding parameters such as offset, count from bin_attribute to this > > new API. > > > > Signed-off-by: Tian Tao <tiantao6@hisilicon.com> > > Cc: Andrew Morton <akpm@linux-foundation.org> > > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > > Cc: Randy Dunlap <rdunlap@infradead.org> > > Cc: Stefano Brivio <sbrivio@redhat.com> > > Cc: Alexander Gordeev <agordeev@linux.ibm.com> > > Cc: "Ma, Jianpeng" <jianpeng.ma@intel.com> > > Cc: Yury Norov <yury.norov@gmail.com> > > Cc: Valentin Schneider <valentin.schneider@arm.com> > > Cc: Peter Zijlstra <peterz@infradead.org> > > Cc: Daniel Bristot de Oliveira <bristot@redhat.com> > > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > Signed-off-by: Barry Song <song.bao.hua@hisilicon.com> > > --- > > include/linux/bitmap.h | 2 ++ > > include/linux/cpumask.h | 63 +++++++++++++++++++++++++++++++++ > > lib/bitmap.c | 78 +++++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 143 insertions(+) > > > > diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h > > index a36cfcec4e77..0de6effa2797 100644 > > --- a/include/linux/bitmap.h > > +++ b/include/linux/bitmap.h > > @@ -226,6 +226,8 @@ void bitmap_copy_le(unsigned long *dst, const unsigned > long *src, unsigned int n > > unsigned int bitmap_ord_to_pos(const unsigned long *bitmap, unsigned int ord, > unsigned int nbits); > > int bitmap_print_to_pagebuf(bool list, char *buf, > > const unsigned long *maskp, int nmaskbits); > > +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 f3689a52bfd0..4b838eb6294c 100644 > > --- a/include/linux/cpumask.h > > +++ b/include/linux/cpumask.h > > @@ -983,6 +983,69 @@ 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 > > + * @list: indicates whether the cpumap must be list > > + * true: print in decimal list format > > + * false: print in hexadecimal bitmask format > > + * > > + * The existing cpumap_print_to_pagebuf() is used by cpu topology and other > > + * drivers to export hexadecimal bitmask and decimal list to userspace by > > + * sysfs ABI. > > + * Drivers might be using a normal attribute for this kind of ABIs. A > > + * normal attribute typically has show entry as below: > > + * static ssize_t example_attribute_show(struct device *dev, > > + * struct device_attribute *attr, char *buf) > > + * { > > + * ... > > + * return cpumap_print_to_pagebuf(true, buf, &pmu_mmdc->cpu); > > + * } > > + * show entry of attribute has no offset and count parameters. this means > > + * the file is limited to one page only. > > + * cpumap_print_to_pagebuf() API works terribly well for this kind of > > + * normal attribute with buf parameter and without offset, count: > > + * cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask) > > + * { > > + * } > > + * The problem is once we have many cpus, we have a chance to make bitmask > > + * or list more than one page. Especially for list, it could be as complex > > + * as 0,3,5,7,9,... We have no simple way to know it exact size. > > + * It turns out bin_attribute is a way to break this limit. bin_attribute > > + * has show entry as below: > > + * static ssize_t > > + * example_bin_attribute_show(struct file *filp, struct kobject *kobj, > > + * struct bin_attribute *attr, char *buf, > > + * loff_t offset, size_t count) > > + * { > > + * ... > > + * } > > + * With the new offset and count parameters, this makes sysfs ABI be able > > + * to support file size more than one page. For example, offset could be > > + * >= 4096. > > + * cpumap_print_to_buf() makes those drivers be able to support large > > + * bitmask and list after they move to use bin_attribute. In result, we > > + * have to pass the corresponding parameters such as off, count from > > + * bin_attribute show entry to this API. > > + * > > + * @mask: the cpumask to copy > > + * @buf: the buffer to copy into > > + * @off: in the string from which we are copying, We copy to @buf > > + * @count: the maximum number of bytes to print > > + * > > + * The function copies the cpumask into the buffer either as comma-separated > > + * list of cpus or hex values of cpumask; Typically used by bin_attribute > to > > + * export cpumask bitmask and list ABI. > > + * > > + * Returns the length of how many bytes have been copied. > > + */ > > +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 9401d39e4722..56bcffe2fa8c 100644 > > --- a/lib/bitmap.c > > +++ b/lib/bitmap.c > > @@ -487,6 +487,84 @@ int bitmap_print_to_pagebuf(bool list, char *buf, const > unsigned long *maskp, > > } > > EXPORT_SYMBOL(bitmap_print_to_pagebuf); > > > > +/** > > + * bitmap_print_to_buf - convert bitmap to list or hex format ASCII string > > + * @list: indicates whether the bitmap must be list > > + * true: print in decimal list format > > + * false: print in hexadecimal bitmask format > > I do not understand "list" or not here. Having binary values in a > function makes it almost impossible to read when they are being called > without having to go dig up the real user. > > Are you using this in both ways? If so, make this the common, static > function and have: > bitmap_print_list_to_buf() > bitmap_print_bitmask_to_buf() > > so that the caller knows exactly what is happening here.
Sounds reasonable to remove bool parameter.
> > > > > + * > > + * The bitmap_print_to_pagebuf() is used indirectly via its cpumap wrapper > > + * cpumap_print_to_pagebuf() or directly by drivers to export hexadecimal > > + * bitmask and decimal list to userspace by sysfs ABI. > > + * Drivers might be using a normal attribute for this kind of ABIs. A > > + * normal attribute typically has show entry as below: > > + * static ssize_t example_attribute_show(struct device *dev, > > + * struct device_attribute *attr, char *buf) > > + * { > > + * ... > > + * return bitmap_print_to_pagebuf(true, buf, &mask, nr_trig_max); > > + * } > > + * show entry of attribute has no offset and count parameters and this > > + * means the file is limited to one page only. > > + * bitmap_print_to_pagebuf() API works terribly well for this kind of > > + * normal attribute with buf parameter and without offset, count: > > + * bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp, > > + * int nmaskbits) > > + * { > > + * } > > + * The problem is once we have a large bitmap, we have a chance to get a > > + * bitmask or list more than one page. Especially for list, it could be > > + * as complex as 0,3,5,7,9,... We have no simple way to know it exact size. > > + * It turns out bin_attribute is a way to break this limit. bin_attribute > > + * has show entry as below: > > + * static ssize_t > > + * example_bin_attribute_show(struct file *filp, struct kobject *kobj, > > + * struct bin_attribute *attr, char *buf, > > + * loff_t offset, size_t count) > > + * { > > + * ... > > + * } > > + * With the new offset and count parameters, this makes sysfs ABI be able > > + * to support file size more than one page. For example, offset could be > > + * >= 4096. > > + * bitmap_print_to_buf() and its cpumap wrapper cpumap_print_to_buf() makes > > + * those drivers be able to support large bitmask and list after they move > > + * to use bin_attribute. In result, we have to pass the corresponding > > + * parameters such as off, count from bin_attribute show entry to this API. > > + * > > + * @buf: buffer into which string is placed > > + * @maskp: pointer to bitmap to convert > > + * @nmaskbits: size of bitmap, in bits > > + * @off: in the string from which we are copying, We copy to @buf > > + * @count: the maximum number of bytes to print > > + * > > + * The role of cpumap_print_to_buf() and cpumap_print_to_pagebuf() is > similar, > > + * the difference is that bitmap_print_to_pagebuf() mainly serves sysfs > > + * attribute with the assumption the destination buffer is exactly one page > > + * and won't be more than one page. cpumap_print_to_buf(), on the other hand, > > + * mainly serves bin_attribute which doesn't work with exact one page, and > it > > + * can break the size limit of converted decimal list and hexadecimal bitmask. > > + * > > + * Returns the number of characters actually printed to @buf > > + */ > > +int bitmap_print_to_buf(bool list, char *buf, const unsigned long *maskp, > > + int nmaskbits, loff_t off, size_t count) > > No need to put the kernel doc for both the .h and .c file, only put it > in one place please (where ever it ties into the kernel documentation) >
Actually they are two different modules. One is cpumap, the other one is bitmap. But they do have some duplicated content. I'd prefer to remove the duplicated part from cpumap.
> thanks, > > greg k-h
Thanks Barry
| |