From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28605C4338F for ; Thu, 5 Aug 2021 23:06:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0C46D60E9B for ; Thu, 5 Aug 2021 23:06:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241620AbhHEXGV convert rfc822-to-8bit (ORCPT ); Thu, 5 Aug 2021 19:06:21 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:7935 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230012AbhHEXGU (ORCPT ); Thu, 5 Aug 2021 19:06:20 -0400 Received: from dggemv704-chm.china.huawei.com (unknown [172.30.72.55]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4GgkdX0tXnz84LD; Fri, 6 Aug 2021 07:02:08 +0800 (CST) Received: from dggpemm000004.china.huawei.com (7.185.36.154) by dggemv704-chm.china.huawei.com (10.3.19.47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Fri, 6 Aug 2021 07:06:00 +0800 Received: from dggemi761-chm.china.huawei.com (10.1.198.147) by dggpemm000004.china.huawei.com (7.185.36.154) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.2176.2; Fri, 6 Aug 2021 07:06:00 +0800 Received: from dggemi761-chm.china.huawei.com ([10.9.49.202]) by dggemi761-chm.china.huawei.com ([10.9.49.202]) with mapi id 15.01.2176.012; Fri, 6 Aug 2021 07:05:59 +0800 From: "Song Bao Hua (Barry Song)" To: Greg KH 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 , "Zengtao (B)" , yangyicong , "tim.c.chen@linux.intel.com" , Linuxarm , "tiantao (H)" , "Jonathan Cameron" Subject: RE: [PATCH v8 1/5] cpumask: introduce cpumap_print_to_buf to support large bitmask and list Thread-Topic: [PATCH v8 1/5] cpumask: introduce cpumap_print_to_buf to support large bitmask and list Thread-Index: AQHXhDyXSaAny2b84UqcVQEdPxb4q6tkYuyAgAEwn8A= Date: Thu, 5 Aug 2021 23:05:59 +0000 Message-ID: <53c5fec4223f4c398b81362acf7441b5@hisilicon.com> References: <20210729054208.1800-1-song.bao.hua@hisilicon.com> <20210729054208.1800-2-song.bao.hua@hisilicon.com> In-Reply-To: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.126.201.246] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org > -----Original Message----- > From: Greg KH [mailto:gregkh@linuxfoundation.org] > Sent: Friday, August 6, 2021 12:53 AM > To: Song Bao Hua (Barry Song) > 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 > ; Zengtao (B) ; > yangyicong ; tim.c.chen@linux.intel.com; Linuxarm > ; tiantao (H) ; Jonathan Cameron > > 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 > > > > 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 > > Cc: Andrew Morton > > Cc: Andy Shevchenko > > Cc: Randy Dunlap > > Cc: Stefano Brivio > > Cc: Alexander Gordeev > > Cc: "Ma, Jianpeng" > > Cc: Yury Norov > > Cc: Valentin Schneider > > Cc: Peter Zijlstra > > Cc: Daniel Bristot de Oliveira > > Reviewed-by: Jonathan Cameron > > Signed-off-by: Barry Song > > --- > > 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