Message ID | 20230523100239.307574-3-miquel.raynal@bootlin.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2024431vqo; Tue, 23 May 2023 03:09:45 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6ogtQw/e8tLDO7k2fgI509pCz8VdMm8vRWo6UCzxomX6r9znteP3LpAFbeCnl4HZJ0vcl+ X-Received: by 2002:a05:6a20:3d02:b0:109:bdaf:6b47 with SMTP id y2-20020a056a203d0200b00109bdaf6b47mr16261845pzi.49.1684836585463; Tue, 23 May 2023 03:09:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684836585; cv=none; d=google.com; s=arc-20160816; b=r5uQGP2tQuPuMF3P44sBRjzjoMGnIWh6SVRagFdj+UFSLSYw95JE7fzgz1x5WU66hh RQFLutSB4dfy/JXIScsPJjKB31M2xF4o+MgQ6n+6Q6PajmsZwpkYCflqMYfNqXNZTFjX ZSTanuY79h9UK54g0+Nzf7M+aHLnmPBcftryioXkb0g+kbrFTjlwnlYVib+0S7J9SAgF 7mUj2w6fP3vW/v3LDMXtPssJTfXFFOD+dbh3ttbtBXIL6lPTfWDGCLOVgltMCdroP3l0 xJSU+iut4p0qhUBMro/mag4mWuAaJhHPBoKJ3wEX7V+fOTAl1m09UzdEBkSC2XCzeJdU /azQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=W5M/vHgzuPPKaMo5s10MhzrRN3WWq1fY96XvfFQ3nlE=; b=qOWXNqCbC8/fcjr5okkukWMGRZ2HXds0pNhqOUF30Yve4ipKOV2iVzrVziWFqu06+m IfIrHOkV3Gv9RTpA59WZbL4tOKba3J22r+SvAraNlY/aUt0ccomb97YjC4tPaHF1vQxC A/SFeIq36wyh84ZnLyQqLda4pBz9A8nkMgukymjJdu81WohgFxc5/8NZyTrHtYE7ZFt3 oVW4780kppzp2tgYTX0qfMOQmgUeV7rYRpAIrQUZzvUDfY62JFVHrHGTyQvsE5YHZCTZ RFjzgCTof3srqZF1ZJPv6xq+tJ41zSNUoXj6lY5ppBIpSJwYmY/5LslqdASePwj8bMg1 yIrA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=YeqwowiJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b24-20020a639318000000b0050bede17e7bsi5978732pge.347.2023.05.23.03.09.30; Tue, 23 May 2023 03:09:45 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=YeqwowiJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229921AbjEWKDA (ORCPT <rfc822;ahmedalshaiji.dev@gmail.com> + 99 others); Tue, 23 May 2023 06:03:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43128 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236316AbjEWKCv (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 23 May 2023 06:02:51 -0400 Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 539EC126 for <linux-kernel@vger.kernel.org>; Tue, 23 May 2023 03:02:44 -0700 (PDT) Received: (Authenticated sender: miquel.raynal@bootlin.com) by mail.gandi.net (Postfix) with ESMTPSA id 1D6351BF205; Tue, 23 May 2023 10:02:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1684836162; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=W5M/vHgzuPPKaMo5s10MhzrRN3WWq1fY96XvfFQ3nlE=; b=YeqwowiJ0aVl/brGpwQk1/8hi9PNM7WuD/z6nzr759He76pNZrB9RQtpWdq/Js4SGfWkKA Z8BPIjub1xWK39MaRo3NtcjizsE3BJhSYVEiHjzFmiDtn0skvlt09APzxAuxSa12mKa7nS HzyaMirNlPtZ63WIVyM+BIhagBgXcF71GusghkOYf9a0q55/OpsEh/zU4w6YWluoIw2j9x r1mBF/gCcThjgFOc5OLKxIFsHiTqHRjKx4jAuPRHPLsetDvVnGzRdHCAK5OGIni1VEiH1f 43F24UOjTUCtyRb4dzJKkMFSP4hi6ahuQLfbhsYpQ9a5ozmOBrkWAde4KzQeGA== From: Miquel Raynal <miquel.raynal@bootlin.com> To: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Luka Perkov <luka.perkov@sartura.hr>, Robert Marko <robert.marko@sartura.hr>, Thomas Petazzoni <thomas.petazzoni@bootlin.com>, <linux-kernel@vger.kernel.org>, Miquel Raynal <miquel.raynal@bootlin.com> Subject: [PATCH 2/2] nvmem: core: Expose cells through sysfs Date: Tue, 23 May 2023 12:02:39 +0200 Message-Id: <20230523100239.307574-3-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230523100239.307574-1-miquel.raynal@bootlin.com> References: <20230523100239.307574-1-miquel.raynal@bootlin.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1766679207347672242?= X-GMAIL-MSGID: =?utf-8?q?1766679207347672242?= |
Series |
NVMEM cells in sysfs
|
|
Commit Message
Miquel Raynal
May 23, 2023, 10:02 a.m. UTC
The binary content of nvmem devices is available to the user so in the
easiest cases, finding the content of a cell is rather easy as it is
just a matter of looking at a known and fixed offset. However, nvmem
layouts have been recently introduced to cope with more advanced
situations, where the offset and size of the cells is not known in
advance or is dynamic. When using layouts, more advanced parsers are
used by the kernel in order to give direct access to the content of each
cell regardless of their position/size in the underlying device, but
these information were not accessible to the user without re-writing the
parser logic in userland.
The current implementation only adds the 'cells' attributes if cells are
found within the device, otherwise the folder does not appear.
Exposed cells are read-only. There is in practice everything in the core
to support a write path, but as I don't see any need for that, I prefer
to keep the interface simple (and probably safer). The interface is
documented as being in the "testing" state which means we can later add
a write attribute if though relevant.
Of course the relevant NVMEM sysfs Kconfig option must be enabled for
this support to be compiled-in.
There is one limitation though: if a layout is built as a module but is
not properly installed in the system and loaded manually with insmod
while the nvmem device driver was built-in, the cells won't appear in
sysfs. But if done like that, the cells won't be usable by the built-in
kernel drivers anyway.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/nvmem/core.c | 135 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 131 insertions(+), 4 deletions(-)
Comments
On Tue, May 23, 2023 at 12:02:39PM +0200, Miquel Raynal wrote: > +/* Cell attributes will be dynamically allocated */ > +static struct attribute_group nvmem_cells_group = { > + .name = "cells", > +}; > + > static const struct attribute_group *nvmem_dev_groups[] = { > &nvmem_bin_group, > + NULL, /* Reserved for exposing cells, if any */ Please don't do this, but rather use the is_visible callback to determine if it should be shown or not. thanks, greg k-h
Hi Greg, gregkh@linuxfoundation.org wrote on Tue, 23 May 2023 17:58:51 +0100: > On Tue, May 23, 2023 at 12:02:39PM +0200, Miquel Raynal wrote: > > +/* Cell attributes will be dynamically allocated */ > > +static struct attribute_group nvmem_cells_group = { > > + .name = "cells", > > +}; > > + > > static const struct attribute_group *nvmem_dev_groups[] = { > > &nvmem_bin_group, > > + NULL, /* Reserved for exposing cells, if any */ > > Please don't do this, but rather use the is_visible callback to > determine if it should be shown or not. Ah, excellent point. Don't know why I overlooked that member. Thanks, Miquèl
Hi Miquel, kernel test robot noticed the following build warnings: [auto build test WARNING on char-misc/char-misc-testing] [also build test WARNING on char-misc/char-misc-next char-misc/char-misc-linus linus/master v6.4-rc3 next-20230523] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Miquel-Raynal/ABI-sysfs-nvmem-cells-Expose-cells-through-sysfs/20230523-203042 base: char-misc/char-misc-testing patch link: https://lore.kernel.org/r/20230523100239.307574-3-miquel.raynal%40bootlin.com patch subject: [PATCH 2/2] nvmem: core: Expose cells through sysfs config: arm-randconfig-r015-20230521 compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project 4faf3aaf28226a4e950c103a14f6fc1d1fdabb1b) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm cross compiling tool for clang build # apt-get install binutils-arm-linux-gnueabi # https://github.com/intel-lab-lkp/linux/commit/22c370b2163e592b9c7b2b1a29c080110dbad018 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Miquel-Raynal/ABI-sysfs-nvmem-cells-Expose-cells-through-sysfs/20230523-203042 git checkout 22c370b2163e592b9c7b2b1a29c080110dbad018 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash drivers/nvmem/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202305240724.z3McDuYM-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/nvmem/core.c:367:6: warning: variable 'read_len' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized] if (IS_ERR(content)) { ^~~~~~~~~~~~~~~ drivers/nvmem/core.c:380:9: note: uninitialized use occurs here return read_len; ^~~~~~~~ drivers/nvmem/core.c:367:2: note: remove the 'if' if its condition is always false if (IS_ERR(content)) { ^~~~~~~~~~~~~~~~~~~~~~ drivers/nvmem/core.c:338:26: note: initialize the variable 'read_len' to silence this warning size_t cell_sz, read_len; ^ = 0 1 warning generated. vim +367 drivers/nvmem/core.c 327 328 static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, 329 const char *id, int index); 330 331 static ssize_t nvmem_cell_attr_read(struct file *filp, struct kobject *kobj, 332 struct bin_attribute *attr, char *buf, 333 loff_t pos, size_t count) 334 { 335 struct nvmem_cell_entry *entry; 336 struct nvmem_cell *cell = NULL; 337 struct nvmem_device *nvmem; 338 size_t cell_sz, read_len; 339 struct device *dev; 340 void *content; 341 342 if (attr->private) 343 dev = attr->private; 344 else 345 dev = kobj_to_dev(kobj); 346 nvmem = to_nvmem_device(dev); 347 348 mutex_lock(&nvmem_mutex); 349 list_for_each_entry(entry, &nvmem->cells, node) { 350 if (strncmp(entry->name, attr->attr.name, XATTR_NAME_MAX)) 351 continue; 352 353 cell = nvmem_create_cell(entry, entry->name, 0); 354 if (IS_ERR(cell)) { 355 mutex_unlock(&nvmem_mutex); 356 return PTR_ERR(cell); 357 } 358 359 break; 360 } 361 mutex_unlock(&nvmem_mutex); 362 363 if (!cell) 364 return -EINVAL; 365 366 content = nvmem_cell_read(cell, &cell_sz); > 367 if (IS_ERR(content)) { 368 count = PTR_ERR(content); 369 goto destroy_cell; 370 } 371 372 read_len = min_t(unsigned int, cell_sz - pos, count); 373 memcpy(buf, content + pos, read_len); 374 kfree(content); 375 376 destroy_cell: 377 kfree_const(cell->id); 378 kfree(cell); 379 380 return read_len; 381 } 382
Hi Miquel, kernel test robot noticed the following build warnings: https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Miquel-Raynal/ABI-sysfs-nvmem-cells-Expose-cells-through-sysfs/20230523-203042 base: char-misc/char-misc-testing patch link: https://lore.kernel.org/r/20230523100239.307574-3-miquel.raynal%40bootlin.com patch subject: [PATCH 2/2] nvmem: core: Expose cells through sysfs config: i386-randconfig-m021-20230525 (https://download.01.org/0day-ci/archive/20230528/202305280054.NloN5RLk-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-12) 11.3.0 If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> | Reported-by: Dan Carpenter <error27@gmail.com> | Closes: https://lore.kernel.org/r/202305280054.NloN5RLk-lkp@intel.com/ smatch warnings: drivers/nvmem/core.c:380 nvmem_cell_attr_read() error: uninitialized symbol 'read_len'. vim +/read_len +380 drivers/nvmem/core.c 22c370b2163e59 Miquel Raynal 2023-05-23 328 static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, 22c370b2163e59 Miquel Raynal 2023-05-23 329 const char *id, int index); 22c370b2163e59 Miquel Raynal 2023-05-23 330 22c370b2163e59 Miquel Raynal 2023-05-23 331 static ssize_t nvmem_cell_attr_read(struct file *filp, struct kobject *kobj, 22c370b2163e59 Miquel Raynal 2023-05-23 332 struct bin_attribute *attr, char *buf, 22c370b2163e59 Miquel Raynal 2023-05-23 333 loff_t pos, size_t count) 22c370b2163e59 Miquel Raynal 2023-05-23 334 { 22c370b2163e59 Miquel Raynal 2023-05-23 335 struct nvmem_cell_entry *entry; 22c370b2163e59 Miquel Raynal 2023-05-23 336 struct nvmem_cell *cell = NULL; 22c370b2163e59 Miquel Raynal 2023-05-23 337 struct nvmem_device *nvmem; 22c370b2163e59 Miquel Raynal 2023-05-23 338 size_t cell_sz, read_len; 22c370b2163e59 Miquel Raynal 2023-05-23 339 struct device *dev; 22c370b2163e59 Miquel Raynal 2023-05-23 340 void *content; 22c370b2163e59 Miquel Raynal 2023-05-23 341 22c370b2163e59 Miquel Raynal 2023-05-23 342 if (attr->private) 22c370b2163e59 Miquel Raynal 2023-05-23 343 dev = attr->private; 22c370b2163e59 Miquel Raynal 2023-05-23 344 else 22c370b2163e59 Miquel Raynal 2023-05-23 345 dev = kobj_to_dev(kobj); 22c370b2163e59 Miquel Raynal 2023-05-23 346 nvmem = to_nvmem_device(dev); 22c370b2163e59 Miquel Raynal 2023-05-23 347 22c370b2163e59 Miquel Raynal 2023-05-23 348 mutex_lock(&nvmem_mutex); 22c370b2163e59 Miquel Raynal 2023-05-23 349 list_for_each_entry(entry, &nvmem->cells, node) { 22c370b2163e59 Miquel Raynal 2023-05-23 350 if (strncmp(entry->name, attr->attr.name, XATTR_NAME_MAX)) 22c370b2163e59 Miquel Raynal 2023-05-23 351 continue; 22c370b2163e59 Miquel Raynal 2023-05-23 352 22c370b2163e59 Miquel Raynal 2023-05-23 353 cell = nvmem_create_cell(entry, entry->name, 0); 22c370b2163e59 Miquel Raynal 2023-05-23 354 if (IS_ERR(cell)) { 22c370b2163e59 Miquel Raynal 2023-05-23 355 mutex_unlock(&nvmem_mutex); 22c370b2163e59 Miquel Raynal 2023-05-23 356 return PTR_ERR(cell); 22c370b2163e59 Miquel Raynal 2023-05-23 357 } 22c370b2163e59 Miquel Raynal 2023-05-23 358 22c370b2163e59 Miquel Raynal 2023-05-23 359 break; 22c370b2163e59 Miquel Raynal 2023-05-23 360 } 22c370b2163e59 Miquel Raynal 2023-05-23 361 mutex_unlock(&nvmem_mutex); 22c370b2163e59 Miquel Raynal 2023-05-23 362 22c370b2163e59 Miquel Raynal 2023-05-23 363 if (!cell) 22c370b2163e59 Miquel Raynal 2023-05-23 364 return -EINVAL; 22c370b2163e59 Miquel Raynal 2023-05-23 365 22c370b2163e59 Miquel Raynal 2023-05-23 366 content = nvmem_cell_read(cell, &cell_sz); 22c370b2163e59 Miquel Raynal 2023-05-23 367 if (IS_ERR(content)) { 22c370b2163e59 Miquel Raynal 2023-05-23 368 count = PTR_ERR(content); 22c370b2163e59 Miquel Raynal 2023-05-23 369 goto destroy_cell; read_len not initialized on this goto path. 22c370b2163e59 Miquel Raynal 2023-05-23 370 } 22c370b2163e59 Miquel Raynal 2023-05-23 371 22c370b2163e59 Miquel Raynal 2023-05-23 372 read_len = min_t(unsigned int, cell_sz - pos, count); 22c370b2163e59 Miquel Raynal 2023-05-23 373 memcpy(buf, content + pos, read_len); 22c370b2163e59 Miquel Raynal 2023-05-23 374 kfree(content); 22c370b2163e59 Miquel Raynal 2023-05-23 375 22c370b2163e59 Miquel Raynal 2023-05-23 376 destroy_cell: 22c370b2163e59 Miquel Raynal 2023-05-23 377 kfree_const(cell->id); 22c370b2163e59 Miquel Raynal 2023-05-23 378 kfree(cell); 22c370b2163e59 Miquel Raynal 2023-05-23 379 22c370b2163e59 Miquel Raynal 2023-05-23 @380 return read_len; ^^^^^^^^^^^^^^^ 22c370b2163e59 Miquel Raynal 2023-05-23 381 }
Hi Greg, miquel.raynal@bootlin.com wrote on Tue, 23 May 2023 19:14:02 +0200: > Hi Greg, > > gregkh@linuxfoundation.org wrote on Tue, 23 May 2023 17:58:51 +0100: > > > On Tue, May 23, 2023 at 12:02:39PM +0200, Miquel Raynal wrote: > > > +/* Cell attributes will be dynamically allocated */ > > > +static struct attribute_group nvmem_cells_group = { > > > + .name = "cells", > > > +}; > > > + > > > static const struct attribute_group *nvmem_dev_groups[] = { > > > &nvmem_bin_group, > > > + NULL, /* Reserved for exposing cells, if any */ > > > > Please don't do this, but rather use the is_visible callback to > > determine if it should be shown or not. > > Ah, excellent point. Don't know why I overlooked that member. Actually, the .is_visible callback only acts on the files and not the directories (created based on the group name). This means whether they are visible or not, the attributes must be valid, the nvmem core cannot just toggle a boolean value with .is_visible because the sysfs core makes a number of checks regarding the content of the attributes, without checking if they are visible at all. I can however expose the "cells" bin group by default by having it listed in the static bin_attribute list and discard it by overwriting the list member with NULL (ie. the opposite of the current solution). This implies two things: I need to provide an empty list of files (otherwise the core warns) and if no list is provided then the "cells" folder will always appear, no matter if there are cells or not exposed by this nvmem device. So the folder can be empty. If this is fine, I can: * Expose the "cells" bin group, * Provide an empty .bin_attrs list (otherwise I get a complain from the sysfs core when the nvmem device does not expose any cell) * Overwrite the dummy .bin_attrs member when the device expose cells, keep it empty otherwise. Otherwise if we prefer avoiding empty folders, I can as well hide the "cells" bin group by writing NULL to the relevant member of the attribute_group list. Let me know what is your preference. Thanks, Miquèl
Hi Dan, dan.carpenter@linaro.org wrote on Mon, 29 May 2023 07:28:59 +0300: > Hi Miquel, > > kernel test robot noticed the following build warnings: > > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > url: https://github.com/intel-lab-lkp/linux/commits/Miquel-Raynal/ABI-sysfs-nvmem-cells-Expose-cells-through-sysfs/20230523-203042 > base: char-misc/char-misc-testing > patch link: https://lore.kernel.org/r/20230523100239.307574-3-miquel.raynal%40bootlin.com > patch subject: [PATCH 2/2] nvmem: core: Expose cells through sysfs > config: i386-randconfig-m021-20230525 (https://download.01.org/0day-ci/archive/20230528/202305280054.NloN5RLk-lkp@intel.com/config) > compiler: gcc-11 (Debian 11.3.0-12) 11.3.0 > > If you fix the issue, kindly add following tag where applicable > | Reported-by: kernel test robot <lkp@intel.com> > | Reported-by: Dan Carpenter <error27@gmail.com> > | Closes: https://lore.kernel.org/r/202305280054.NloN5RLk-lkp@intel.com/ > > smatch warnings: > drivers/nvmem/core.c:380 nvmem_cell_attr_read() error: uninitialized symbol 'read_len'. > > vim +/read_len +380 drivers/nvmem/core.c > > 22c370b2163e59 Miquel Raynal 2023-05-23 328 static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, > 22c370b2163e59 Miquel Raynal 2023-05-23 329 const char *id, int index); > 22c370b2163e59 Miquel Raynal 2023-05-23 330 > 22c370b2163e59 Miquel Raynal 2023-05-23 331 static ssize_t nvmem_cell_attr_read(struct file *filp, struct kobject *kobj, > 22c370b2163e59 Miquel Raynal 2023-05-23 332 struct bin_attribute *attr, char *buf, > 22c370b2163e59 Miquel Raynal 2023-05-23 333 loff_t pos, size_t count) > 22c370b2163e59 Miquel Raynal 2023-05-23 334 { > 22c370b2163e59 Miquel Raynal 2023-05-23 335 struct nvmem_cell_entry *entry; > 22c370b2163e59 Miquel Raynal 2023-05-23 336 struct nvmem_cell *cell = NULL; > 22c370b2163e59 Miquel Raynal 2023-05-23 337 struct nvmem_device *nvmem; > 22c370b2163e59 Miquel Raynal 2023-05-23 338 size_t cell_sz, read_len; > 22c370b2163e59 Miquel Raynal 2023-05-23 339 struct device *dev; > 22c370b2163e59 Miquel Raynal 2023-05-23 340 void *content; > 22c370b2163e59 Miquel Raynal 2023-05-23 341 > 22c370b2163e59 Miquel Raynal 2023-05-23 342 if (attr->private) > 22c370b2163e59 Miquel Raynal 2023-05-23 343 dev = attr->private; > 22c370b2163e59 Miquel Raynal 2023-05-23 344 else > 22c370b2163e59 Miquel Raynal 2023-05-23 345 dev = kobj_to_dev(kobj); > 22c370b2163e59 Miquel Raynal 2023-05-23 346 nvmem = to_nvmem_device(dev); > 22c370b2163e59 Miquel Raynal 2023-05-23 347 > 22c370b2163e59 Miquel Raynal 2023-05-23 348 mutex_lock(&nvmem_mutex); > 22c370b2163e59 Miquel Raynal 2023-05-23 349 list_for_each_entry(entry, &nvmem->cells, node) { > 22c370b2163e59 Miquel Raynal 2023-05-23 350 if (strncmp(entry->name, attr->attr.name, XATTR_NAME_MAX)) > 22c370b2163e59 Miquel Raynal 2023-05-23 351 continue; > 22c370b2163e59 Miquel Raynal 2023-05-23 352 > 22c370b2163e59 Miquel Raynal 2023-05-23 353 cell = nvmem_create_cell(entry, entry->name, 0); > 22c370b2163e59 Miquel Raynal 2023-05-23 354 if (IS_ERR(cell)) { > 22c370b2163e59 Miquel Raynal 2023-05-23 355 mutex_unlock(&nvmem_mutex); > 22c370b2163e59 Miquel Raynal 2023-05-23 356 return PTR_ERR(cell); > 22c370b2163e59 Miquel Raynal 2023-05-23 357 } > 22c370b2163e59 Miquel Raynal 2023-05-23 358 > 22c370b2163e59 Miquel Raynal 2023-05-23 359 break; > 22c370b2163e59 Miquel Raynal 2023-05-23 360 } > 22c370b2163e59 Miquel Raynal 2023-05-23 361 mutex_unlock(&nvmem_mutex); > 22c370b2163e59 Miquel Raynal 2023-05-23 362 > 22c370b2163e59 Miquel Raynal 2023-05-23 363 if (!cell) > 22c370b2163e59 Miquel Raynal 2023-05-23 364 return -EINVAL; > 22c370b2163e59 Miquel Raynal 2023-05-23 365 > 22c370b2163e59 Miquel Raynal 2023-05-23 366 content = nvmem_cell_read(cell, &cell_sz); > 22c370b2163e59 Miquel Raynal 2023-05-23 367 if (IS_ERR(content)) { > 22c370b2163e59 Miquel Raynal 2023-05-23 368 count = PTR_ERR(content); > 22c370b2163e59 Miquel Raynal 2023-05-23 369 goto destroy_cell; > > read_len not initialized on this goto path. It should be: read_len = PTR_ERR... I will correct this in the next version, thanks for the report. > > 22c370b2163e59 Miquel Raynal 2023-05-23 370 } > 22c370b2163e59 Miquel Raynal 2023-05-23 371 > 22c370b2163e59 Miquel Raynal 2023-05-23 372 read_len = min_t(unsigned int, cell_sz - pos, count); > 22c370b2163e59 Miquel Raynal 2023-05-23 373 memcpy(buf, content + pos, read_len); > 22c370b2163e59 Miquel Raynal 2023-05-23 374 kfree(content); > 22c370b2163e59 Miquel Raynal 2023-05-23 375 > 22c370b2163e59 Miquel Raynal 2023-05-23 376 destroy_cell: > 22c370b2163e59 Miquel Raynal 2023-05-23 377 kfree_const(cell->id); > 22c370b2163e59 Miquel Raynal 2023-05-23 378 kfree(cell); > 22c370b2163e59 Miquel Raynal 2023-05-23 379 > 22c370b2163e59 Miquel Raynal 2023-05-23 @380 return read_len; > ^^^^^^^^^^^^^^^ > > 22c370b2163e59 Miquel Raynal 2023-05-23 381 } > Thanks, Miquèl
On Mon, May 29, 2023 at 12:12:26PM +0200, Miquel Raynal wrote: > Hi Greg, > > miquel.raynal@bootlin.com wrote on Tue, 23 May 2023 19:14:02 +0200: > > > Hi Greg, > > > > gregkh@linuxfoundation.org wrote on Tue, 23 May 2023 17:58:51 +0100: > > > > > On Tue, May 23, 2023 at 12:02:39PM +0200, Miquel Raynal wrote: > > > > +/* Cell attributes will be dynamically allocated */ > > > > +static struct attribute_group nvmem_cells_group = { > > > > + .name = "cells", > > > > +}; > > > > + > > > > static const struct attribute_group *nvmem_dev_groups[] = { > > > > &nvmem_bin_group, > > > > + NULL, /* Reserved for exposing cells, if any */ > > > > > > Please don't do this, but rather use the is_visible callback to > > > determine if it should be shown or not. > > > > Ah, excellent point. Don't know why I overlooked that member. > > Actually, the .is_visible callback only acts on the files and > not the directories (created based on the group name). That is true, I have a non-working patch somewhere around here that will not create the directory if no files are in that directory, and need to get that working someday... > This > means whether they are visible or not, the attributes must be > valid, the nvmem core cannot just toggle a boolean value with > .is_visible because the sysfs core makes a number of checks > regarding the content of the attributes, without checking if > they are visible at all. You can't toggle a value, that's not how is_visible works. It's a callback at the creation time, you do know if you should, or should not, show the files at creation time, right? If so, all should be fine, just ignore the empty directory, it's fine. And hopefully one day, it will not be created if there are no files in it. If I can ever get that patch working... > I can however expose the "cells" bin group by default by having > it listed in the static bin_attribute list and discard it by > overwriting the list member with NULL (ie. the opposite of the current > solution). Ick, no, please don't do that. attribute lists should be able to be put into read-only memory, and are not set up to be dynamically messed with like this at all. thanks, greg k-h
Hi Greg, gregkh@linuxfoundation.org wrote on Mon, 29 May 2023 14:05:30 +0100: > On Mon, May 29, 2023 at 12:12:26PM +0200, Miquel Raynal wrote: > > Hi Greg, > > > > miquel.raynal@bootlin.com wrote on Tue, 23 May 2023 19:14:02 +0200: > > > > > Hi Greg, > > > > > > gregkh@linuxfoundation.org wrote on Tue, 23 May 2023 17:58:51 +0100: > > > > > > > On Tue, May 23, 2023 at 12:02:39PM +0200, Miquel Raynal wrote: > > > > > +/* Cell attributes will be dynamically allocated */ > > > > > +static struct attribute_group nvmem_cells_group = { > > > > > + .name = "cells", > > > > > +}; > > > > > + > > > > > static const struct attribute_group *nvmem_dev_groups[] = { > > > > > &nvmem_bin_group, > > > > > + NULL, /* Reserved for exposing cells, if any */ > > > > > > > > Please don't do this, but rather use the is_visible callback to > > > > determine if it should be shown or not. > > > > > > Ah, excellent point. Don't know why I overlooked that member. > > > > Actually, the .is_visible callback only acts on the files and > > not the directories (created based on the group name). > > That is true, I have a non-working patch somewhere around here that will > not create the directory if no files are in that directory, and need to > get that working someday... I see, indeed that would be a nice addition. > > This > > means whether they are visible or not, the attributes must be > > valid, the nvmem core cannot just toggle a boolean value with > > .is_visible because the sysfs core makes a number of checks > > regarding the content of the attributes, without checking if > > they are visible at all. > > You can't toggle a value, that's not how is_visible works. It's a > callback at the creation time, you do know if you should, or should not, > show the files at creation time, right? I think I should be able to do that. > If so, all should be fine, just ignore the empty directory, it's fine. Ok. > And hopefully one day, it will not be created if there are no files in > it. If I can ever get that patch working... > > > I can however expose the "cells" bin group by default by having > > it listed in the static bin_attribute list and discard it by > > overwriting the list member with NULL (ie. the opposite of the current > > solution). > > Ick, no, please don't do that. attribute lists should be able to be put > into read-only memory, and are not set up to be dynamically messed with > like this at all. I get the idea, makes sense. However in my case, the list of attribute groups can lay into RO memory, that's fine, but the attribute group for the cells will not. Indeed, the .bin_attrs list must be populated at run time as we do not know it's size at compilation time. I hope this is acceptable. Thanks, Miquèl
On Mon, May 29, 2023 at 03:35:39PM +0200, Miquel Raynal wrote: > Hi Greg, > > gregkh@linuxfoundation.org wrote on Mon, 29 May 2023 14:05:30 +0100: > > > On Mon, May 29, 2023 at 12:12:26PM +0200, Miquel Raynal wrote: > > > Hi Greg, > > > > > > miquel.raynal@bootlin.com wrote on Tue, 23 May 2023 19:14:02 +0200: > > > > > > > Hi Greg, > > > > > > > > gregkh@linuxfoundation.org wrote on Tue, 23 May 2023 17:58:51 +0100: > > > > > > > > > On Tue, May 23, 2023 at 12:02:39PM +0200, Miquel Raynal wrote: > > > > > > +/* Cell attributes will be dynamically allocated */ > > > > > > +static struct attribute_group nvmem_cells_group = { > > > > > > + .name = "cells", > > > > > > +}; > > > > > > + > > > > > > static const struct attribute_group *nvmem_dev_groups[] = { > > > > > > &nvmem_bin_group, > > > > > > + NULL, /* Reserved for exposing cells, if any */ > > > > > > > > > > Please don't do this, but rather use the is_visible callback to > > > > > determine if it should be shown or not. > > > > > > > > Ah, excellent point. Don't know why I overlooked that member. > > > > > > Actually, the .is_visible callback only acts on the files and > > > not the directories (created based on the group name). > > > > That is true, I have a non-working patch somewhere around here that will > > not create the directory if no files are in that directory, and need to > > get that working someday... > > I see, indeed that would be a nice addition. > > > > This > > > means whether they are visible or not, the attributes must be > > > valid, the nvmem core cannot just toggle a boolean value with > > > .is_visible because the sysfs core makes a number of checks > > > regarding the content of the attributes, without checking if > > > they are visible at all. > > > > You can't toggle a value, that's not how is_visible works. It's a > > callback at the creation time, you do know if you should, or should not, > > show the files at creation time, right? > > I think I should be able to do that. > > > If so, all should be fine, just ignore the empty directory, it's fine. > > Ok. > > > And hopefully one day, it will not be created if there are no files in > > it. If I can ever get that patch working... > > > > > I can however expose the "cells" bin group by default by having > > > it listed in the static bin_attribute list and discard it by > > > overwriting the list member with NULL (ie. the opposite of the current > > > solution). > > > > Ick, no, please don't do that. attribute lists should be able to be put > > into read-only memory, and are not set up to be dynamically messed with > > like this at all. > > I get the idea, makes sense. > > However in my case, the list of attribute groups can lay into RO > memory, that's fine, but the attribute group for the cells > will not. Indeed, the .bin_attrs list must be populated at run time > as we do not know it's size at compilation time. Ick. I thought we had a way to update the size of a sysfs file dynamically but I guess not. So that's ok for now. thanks, greg k-h
Hi Greg, gregkh@linuxfoundation.org wrote on Mon, 29 May 2023 14:43:51 +0100: > On Mon, May 29, 2023 at 03:35:39PM +0200, Miquel Raynal wrote: > > Hi Greg, > > > > gregkh@linuxfoundation.org wrote on Mon, 29 May 2023 14:05:30 +0100: > > > > > On Mon, May 29, 2023 at 12:12:26PM +0200, Miquel Raynal wrote: > > > > Hi Greg, > > > > > > > > miquel.raynal@bootlin.com wrote on Tue, 23 May 2023 19:14:02 +0200: > > > > > > > > > Hi Greg, > > > > > > > > > > gregkh@linuxfoundation.org wrote on Tue, 23 May 2023 17:58:51 +0100: > > > > > > > > > > > On Tue, May 23, 2023 at 12:02:39PM +0200, Miquel Raynal wrote: > > > > > > > +/* Cell attributes will be dynamically allocated */ > > > > > > > +static struct attribute_group nvmem_cells_group = { > > > > > > > + .name = "cells", > > > > > > > +}; > > > > > > > + > > > > > > > static const struct attribute_group *nvmem_dev_groups[] = { > > > > > > > &nvmem_bin_group, > > > > > > > + NULL, /* Reserved for exposing cells, if any */ > > > > > > > > > > > > Please don't do this, but rather use the is_visible callback to > > > > > > determine if it should be shown or not. > > > > > > > > > > Ah, excellent point. Don't know why I overlooked that member. > > > > > > > > Actually, the .is_visible callback only acts on the files and > > > > not the directories (created based on the group name). > > > > > > That is true, I have a non-working patch somewhere around here that will > > > not create the directory if no files are in that directory, and need to > > > get that working someday... > > > > I see, indeed that would be a nice addition. > > > > > > This > > > > means whether they are visible or not, the attributes must be > > > > valid, the nvmem core cannot just toggle a boolean value with > > > > .is_visible because the sysfs core makes a number of checks > > > > regarding the content of the attributes, without checking if > > > > they are visible at all. > > > > > > You can't toggle a value, that's not how is_visible works. It's a > > > callback at the creation time, you do know if you should, or should not, > > > show the files at creation time, right? > > > > I think I should be able to do that. > > > > > If so, all should be fine, just ignore the empty directory, it's fine. > > > > Ok. > > > > > And hopefully one day, it will not be created if there are no files in > > > it. If I can ever get that patch working... > > > > > > > I can however expose the "cells" bin group by default by having > > > > it listed in the static bin_attribute list and discard it by > > > > overwriting the list member with NULL (ie. the opposite of the current > > > > solution). > > > > > > Ick, no, please don't do that. attribute lists should be able to be put > > > into read-only memory, and are not set up to be dynamically messed with > > > like this at all. > > > > I get the idea, makes sense. > > > > However in my case, the list of attribute groups can lay into RO > > memory, that's fine, but the attribute group for the cells > > will not. Indeed, the .bin_attrs list must be populated at run time > > as we do not know it's size at compilation time. > > Ick. I thought we had a way to update the size of a sysfs file > dynamically but I guess not. So that's ok for now. To be exact, there is a hook to provide the size of a file at runtime (and I use it), but here I am referring to the number of files in the directory. In this case, the number of files depends on the number of cells, which are discovered dynamically at run time. Hence, the attribute_group for the cells needs a writable .bin_attrs member. Thanks, Miquèl
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 342cd380b420..234b2f232854 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -325,6 +325,61 @@ static umode_t nvmem_bin_attr_is_visible(struct kobject *kobj, return nvmem_bin_attr_get_umode(nvmem); } +static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, + const char *id, int index); + +static ssize_t nvmem_cell_attr_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t pos, size_t count) +{ + struct nvmem_cell_entry *entry; + struct nvmem_cell *cell = NULL; + struct nvmem_device *nvmem; + size_t cell_sz, read_len; + struct device *dev; + void *content; + + if (attr->private) + dev = attr->private; + else + dev = kobj_to_dev(kobj); + nvmem = to_nvmem_device(dev); + + mutex_lock(&nvmem_mutex); + list_for_each_entry(entry, &nvmem->cells, node) { + if (strncmp(entry->name, attr->attr.name, XATTR_NAME_MAX)) + continue; + + cell = nvmem_create_cell(entry, entry->name, 0); + if (IS_ERR(cell)) { + mutex_unlock(&nvmem_mutex); + return PTR_ERR(cell); + } + + break; + } + mutex_unlock(&nvmem_mutex); + + if (!cell) + return -EINVAL; + + content = nvmem_cell_read(cell, &cell_sz); + if (IS_ERR(content)) { + count = PTR_ERR(content); + goto destroy_cell; + } + + read_len = min_t(unsigned int, cell_sz - pos, count); + memcpy(buf, content + pos, read_len); + kfree(content); + +destroy_cell: + kfree_const(cell->id); + kfree(cell); + + return read_len; +} + /* default read/write permissions */ static struct bin_attribute bin_attr_rw_nvmem = { .attr = { @@ -346,8 +401,14 @@ static const struct attribute_group nvmem_bin_group = { .is_bin_visible = nvmem_bin_attr_is_visible, }; +/* Cell attributes will be dynamically allocated */ +static struct attribute_group nvmem_cells_group = { + .name = "cells", +}; + static const struct attribute_group *nvmem_dev_groups[] = { &nvmem_bin_group, + NULL, /* Reserved for exposing cells, if any */ NULL, }; @@ -406,6 +467,66 @@ static void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem, device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); } +static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem) +{ + struct bin_attribute **cells_attrs, *attrs; + struct nvmem_cell_entry *entry; + unsigned int ncells = 0, i = 0; + int ret = 0; + + mutex_lock(&nvmem_mutex); + + /* Allocate an array of attributes */ + list_for_each_entry(entry, &nvmem->cells, node) + ncells++; + + if (!ncells) + goto unlock_mutex; + + cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1, sizeof(struct bin_attribute *), + GFP_KERNEL); + if (!cells_attrs) { + ret = -ENOMEM; + goto unlock_mutex; + } + + attrs = devm_kcalloc(&nvmem->dev, ncells, sizeof(struct bin_attribute), + GFP_KERNEL); + if (!attrs) { + ret = -ENOMEM; + goto unlock_mutex; + } + + /* Initialize each attribute to have the name of a cell */ + list_for_each_entry(entry, &nvmem->cells, node) { + sysfs_bin_attr_init(&attrs[i]); + attrs[i].attr.name = kstrdup(entry->name, GFP_KERNEL); + attrs[i].attr.mode = 0444; + attrs[i].size = entry->bytes; + attrs[i].read = &nvmem_cell_attr_read; + if (!attrs[i].attr.name) { + ret = -ENOMEM; + goto unlock_mutex; + } + + cells_attrs[i] = &attrs[i]; + i++; + } + + nvmem_cells_group.bin_attrs = cells_attrs; + + /* Fill the attribute group structure with the cells member */ + for (i = 0;; i++) + if (!nvmem_dev_groups[i]) + break; + nvmem_dev_groups[i] = &nvmem_cells_group; + +unlock_mutex: + mutex_unlock(&nvmem_mutex); + + return ret; +} + #else /* CONFIG_NVMEM_SYSFS */ static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, @@ -976,16 +1097,22 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) if (rval) goto err_remove_cells; + rval = nvmem_add_cells_from_layout(nvmem); + if (rval) + goto err_remove_cells; + +#ifdef CONFIG_NVMEM_SYSFS + rval = nvmem_populate_sysfs_cells(nvmem); + if (rval) + goto err_remove_cells; +#endif + dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); rval = device_add(&nvmem->dev); if (rval) goto err_remove_cells; - rval = nvmem_add_cells_from_layout(nvmem); - if (rval) - goto err_remove_cells; - blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); return nvmem;