From patchwork Wed Oct 9 16:13:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 13828736 X-Patchwork-Delegate: johannes@sipsolutions.net Received: from sipsolutions.net (s3.sipsolutions.net [168.119.38.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8328B1F12E0; Wed, 9 Oct 2024 16:13:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=168.119.38.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728490439; cv=none; b=hu7LZYp0KwbgGUEcxaQBOAu/Mon3SR3MV8LQnS3ibc9BLr2CygZLElu7von6HPkwkYy0iTtX0GgYNRmYdVO6Hee6saVn6vNc1EKtOE4lPseJsQX58/aHRort8fBSdw6GidaBrWIdqi0ZwhM8Qw3xukEYAYEkOG9oGVFQFWVxCgE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728490439; c=relaxed/simple; bh=qRZvWcyVcwrVYWstlIygwj9U6DowSqdfX3y1tzfiuZI=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=c47CNLAdXyp1jZFw9FHglvQiD/6HrutAh0fshdzkcgy3MW1SX9FBrQPOk6lzy21l7meFMcdoTmjNp0N97MMLva3U98lzO0gbg+wRB1nMt9tA8nARxhdeqjs+7muBE7ouKw3qPn+grlUU0pTEBG3uUVbFsDu7+rQM+aOo9YlOIVU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sipsolutions.net; spf=pass smtp.mailfrom=sipsolutions.net; dkim=pass (2048-bit key) header.d=sipsolutions.net header.i=@sipsolutions.net header.b=XZwgczbi; arc=none smtp.client-ip=168.119.38.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sipsolutions.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sipsolutions.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sipsolutions.net header.i=@sipsolutions.net header.b="XZwgczbi" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version: Message-ID:Date:Subject:Cc:To:From:Content-Type:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-To:Resent-Cc: Resent-Message-ID:In-Reply-To:References; bh=1HmsbQWOogsqSu+86NEf8pVg/nZITnxbJ2Nd/7dDfaw=; t=1728490437; x=1729700037; b=XZwgczbims880NQmJygONRD9v+fki5dYMhd/d2nBYE/LQRg3QT/LR9SxreMy4vJYAlMF/E8q43s ks/OB0QeofHZ0NvgrZJpqL11JmAZ4rrqR4oWURUna5+G/DOImMVT0L9q21EoXe8jYTbABJgLX1wSg l90yOSNmYunSeQ9KWtU6jpoi/fRDyJJnAZgtQ3skDYrO1ihloXv+PYm+FOmbg8PWcAgWySQ3YosV0 MgcKX+j64J14aCRwfWYDt+fW4VENThdeF9U01RZkyAI1TDFjeXdnAqbyFB644rA4wECLPlRIYZqee VKBDRh6Ht8XGKA6wcn/1kOiaEpi61zthtvvw==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.98) (envelope-from ) id 1syZJs-00000005EUI-3SrZ; Wed, 09 Oct 2024 18:13:49 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , "Rafael J. Wysocki" , Alexander Viro , Johannes Berg Subject: [RFC PATCH 1/2] debugfs: add small file operations for most files Date: Wed, 9 Oct 2024 18:13:39 +0200 Message-ID: <20241009181339.0b1a6eaef573.Ia80b55e934bbfc45ce0df42a3233d34b35508046@changeid> X-Mailer: git-send-email 2.46.2 Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Johannes Berg As struct file_operations is really big, but (most) debugfs files only use simple_open, read and write, and don't need anything else, this wastes a lot of space for NULL pointers. Add a struct debugfs_short_fops and some bookkeeping code in debugfs so that users can use that with debugfs_create_file() using _Generic to figure out which function to use. Converting mac80211 to use it where possible saves quite a bit of space: 1010127 205064 1220 1216411 128f9b net/mac80211/mac80211.ko (before) 981199 205064 1220 1187483 121e9b net/mac80211/mac80211.ko (after) ------- -28928 = ~28KiB With a marginal space cost in debugfs: 8701 550 16 9267 2433 fs/debugfs/inode.o (before) 25233 325 32 25590 63f6 fs/debugfs/file.o (before) 8914 558 16 9488 2510 fs/debugfs/inode.o (after) 25380 325 32 25737 6489 fs/debugfs/file.o (after) --------------- +360 +8 (All on x86-64) A simple spatch suggests there are more than 300 instances, not even counting the ones hidden in macros like in mac80211, that could be trivially converted, for additional savings of about 240 bytes for each. Signed-off-by: Johannes Berg --- fs/debugfs/file.c | 100 ++++++++++++++++++++++++++++------------ fs/debugfs/inode.c | 63 +++++++++++-------------- fs/debugfs/internal.h | 6 +++ include/linux/debugfs.h | 60 ++++++++++++++++++++++-- 4 files changed, 159 insertions(+), 70 deletions(-) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 67299e8b734e..47dc96dfe386 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -100,8 +100,16 @@ int debugfs_file_get(struct dentry *dentry) if (!fsd) return -ENOMEM; - fsd->real_fops = (void *)((unsigned long)d_fsd & - ~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT); + if ((unsigned long)d_fsd & DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT) { + fsd->real_fops = NULL; + fsd->short_fops = (void *)((unsigned long)d_fsd & + ~(DEBUGFS_FSDATA_IS_REAL_FOPS_BIT | + DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT)); + } else { + fsd->real_fops = (void *)((unsigned long)d_fsd & + ~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT); + fsd->short_fops = NULL; + } refcount_set(&fsd->active_users, 1); init_completion(&fsd->active_users_drained); INIT_LIST_HEAD(&fsd->cancellations); @@ -241,9 +249,10 @@ static int debugfs_locked_down(struct inode *inode, { if ((inode->i_mode & 07777 & ~0444) == 0 && !(filp->f_mode & FMODE_WRITE) && - !real_fops->unlocked_ioctl && - !real_fops->compat_ioctl && - !real_fops->mmap) + (!real_fops || + (!real_fops->unlocked_ioctl && + !real_fops->compat_ioctl && + !real_fops->mmap))) return 0; if (security_locked_down(LOCKDOWN_DEBUGFS)) @@ -316,19 +325,38 @@ static ret_type full_proxy_ ## name(proto) \ return r; \ } -FULL_PROXY_FUNC(llseek, loff_t, filp, - PROTO(struct file *filp, loff_t offset, int whence), - ARGS(filp, offset, whence)); +#define FULL_PROXY_FUNC_BOTH(name, ret_type, filp, proto, args) \ +static ret_type full_proxy_ ## name(proto) \ +{ \ + struct dentry *dentry = F_DENTRY(filp); \ + struct debugfs_fsdata *fsd; \ + ret_type r; \ + \ + r = debugfs_file_get(dentry); \ + if (unlikely(r)) \ + return r; \ + fsd = dentry->d_fsdata; \ + if (fsd->real_fops) \ + r = fsd->real_fops->name(args); \ + else \ + r = fsd->short_fops->name(args); \ + debugfs_file_put(dentry); \ + return r; \ +} -FULL_PROXY_FUNC(read, ssize_t, filp, - PROTO(struct file *filp, char __user *buf, size_t size, - loff_t *ppos), - ARGS(filp, buf, size, ppos)); +FULL_PROXY_FUNC_BOTH(llseek, loff_t, filp, + PROTO(struct file *filp, loff_t offset, int whence), + ARGS(filp, offset, whence)); -FULL_PROXY_FUNC(write, ssize_t, filp, - PROTO(struct file *filp, const char __user *buf, size_t size, - loff_t *ppos), - ARGS(filp, buf, size, ppos)); +FULL_PROXY_FUNC_BOTH(read, ssize_t, filp, + PROTO(struct file *filp, char __user *buf, size_t size, + loff_t *ppos), + ARGS(filp, buf, size, ppos)); + +FULL_PROXY_FUNC_BOTH(write, ssize_t, filp, + PROTO(struct file *filp, const char __user *buf, + size_t size, loff_t *ppos), + ARGS(filp, buf, size, ppos)); FULL_PROXY_FUNC(unlocked_ioctl, long, filp, PROTO(struct file *filp, unsigned int cmd, unsigned long arg), @@ -363,7 +391,7 @@ static int full_proxy_release(struct inode *inode, struct file *filp) * not to leak any resources. Releasers must not assume that * ->i_private is still being meaningful here. */ - if (real_fops->release) + if (real_fops && real_fops->release) r = real_fops->release(inode, filp); replace_fops(filp, d_inode(dentry)->i_fop); @@ -373,39 +401,48 @@ static int full_proxy_release(struct inode *inode, struct file *filp) } static void __full_proxy_fops_init(struct file_operations *proxy_fops, - const struct file_operations *real_fops) + struct debugfs_fsdata *fsd) { proxy_fops->release = full_proxy_release; - if (real_fops->llseek) + + if ((fsd->real_fops && fsd->real_fops->llseek) || + (fsd->short_fops && fsd->short_fops->llseek)) proxy_fops->llseek = full_proxy_llseek; - if (real_fops->read) + + if ((fsd->real_fops && fsd->real_fops->read) || + (fsd->short_fops && fsd->short_fops->read)) proxy_fops->read = full_proxy_read; - if (real_fops->write) + + if ((fsd->real_fops && fsd->real_fops->write) || + (fsd->short_fops && fsd->short_fops->write)) proxy_fops->write = full_proxy_write; - if (real_fops->poll) + + if (fsd->real_fops && fsd->real_fops->poll) proxy_fops->poll = full_proxy_poll; - if (real_fops->unlocked_ioctl) + + if (fsd->real_fops && fsd->real_fops->unlocked_ioctl) proxy_fops->unlocked_ioctl = full_proxy_unlocked_ioctl; } static int full_proxy_open(struct inode *inode, struct file *filp) { struct dentry *dentry = F_DENTRY(filp); - const struct file_operations *real_fops = NULL; + const struct file_operations *real_fops; struct file_operations *proxy_fops = NULL; + struct debugfs_fsdata *fsd; int r; r = debugfs_file_get(dentry); if (r) return r == -EIO ? -ENOENT : r; - real_fops = debugfs_real_fops(filp); - + fsd = dentry->d_fsdata; + real_fops = fsd->real_fops; r = debugfs_locked_down(inode, filp, real_fops); if (r) goto out; - if (!fops_get(real_fops)) { + if (real_fops && !fops_get(real_fops)) { #ifdef CONFIG_MODULES if (real_fops->owner && real_fops->owner->state == MODULE_STATE_GOING) { @@ -426,11 +463,14 @@ static int full_proxy_open(struct inode *inode, struct file *filp) r = -ENOMEM; goto free_proxy; } - __full_proxy_fops_init(proxy_fops, real_fops); + __full_proxy_fops_init(proxy_fops, fsd); replace_fops(filp, proxy_fops); - if (real_fops->open) { - r = real_fops->open(inode, filp); + if (!real_fops || real_fops->open) { + if (real_fops) + r = real_fops->open(inode, filp); + else + r = simple_open(inode, filp); if (r) { replace_fops(filp, d_inode(dentry)->i_fop); goto free_proxy; diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 66d9b3b4c588..38a9c7eb97e6 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -412,7 +412,7 @@ static struct dentry *end_creating(struct dentry *dentry) static struct dentry *__debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *proxy_fops, - const struct file_operations *real_fops) + const void *real_fops) { struct dentry *dentry; struct inode *inode; @@ -450,49 +450,38 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode, return end_creating(dentry); } -/** - * debugfs_create_file - create a file in the debugfs filesystem - * @name: a pointer to a string containing the name of the file to create. - * @mode: the permission that the file should have. - * @parent: a pointer to the parent dentry for this file. This should be a - * directory dentry if set. If this parameter is NULL, then the - * file will be created in the root of the debugfs filesystem. - * @data: a pointer to something that the caller will want to get to later - * on. The inode.i_private pointer will point to this value on - * the open() call. - * @fops: a pointer to a struct file_operations that should be used for - * this file. - * - * This is the basic "create a file" function for debugfs. It allows for a - * wide range of flexibility in creating a file, or a directory (if you want - * to create a directory, the debugfs_create_dir() function is - * recommended to be used instead.) - * - * This function will return a pointer to a dentry if it succeeds. This - * pointer must be passed to the debugfs_remove() function when the file is - * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be - * returned. - * - * If debugfs is not enabled in the kernel, the value -%ENODEV will be - * returned. - * - * NOTE: it's expected that most callers should _ignore_ the errors returned - * by this function. Other debugfs functions handle the fact that the "dentry" - * passed to them could be an error and they don't crash in that case. - * Drivers should generally work fine even if debugfs fails to init anyway. - */ -struct dentry *debugfs_create_file(const char *name, umode_t mode, - struct dentry *parent, void *data, - const struct file_operations *fops) +struct dentry *debugfs_create_file_full(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops) { + if (WARN_ON((unsigned long)fops & + (DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT | + DEBUGFS_FSDATA_IS_REAL_FOPS_BIT))) + return ERR_PTR(-EINVAL); return __debugfs_create_file(name, mode, parent, data, fops ? &debugfs_full_proxy_file_operations : &debugfs_noop_file_operations, fops); } -EXPORT_SYMBOL_GPL(debugfs_create_file); +EXPORT_SYMBOL_GPL(debugfs_create_file_full); + +struct dentry *debugfs_create_file_short(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct debugfs_short_fops *fops) +{ + if (WARN_ON((unsigned long)fops & + (DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT | + DEBUGFS_FSDATA_IS_REAL_FOPS_BIT))) + return ERR_PTR(-EINVAL); + + return __debugfs_create_file(name, mode, parent, data, + fops ? &debugfs_full_proxy_file_operations : + &debugfs_noop_file_operations, + (const void *)((unsigned long)fops | + DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT)); +} +EXPORT_SYMBOL_GPL(debugfs_create_file_short); /** * debugfs_create_file_unsafe - create a file in the debugfs filesystem diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h index dae80c2a469e..a3edfa4f0d8e 100644 --- a/fs/debugfs/internal.h +++ b/fs/debugfs/internal.h @@ -18,6 +18,7 @@ extern const struct file_operations debugfs_full_proxy_file_operations; struct debugfs_fsdata { const struct file_operations *real_fops; + const struct debugfs_short_fops *short_fops; union { /* automount_fn is used when real_fops is NULL */ debugfs_automount_t automount; @@ -39,6 +40,11 @@ struct debugfs_fsdata { * pointer gets its lowest bit set. */ #define DEBUGFS_FSDATA_IS_REAL_FOPS_BIT BIT(0) +/* + * A dentry's ->d_fsdata, when pointing to real fops, is with + * short fops instead of full fops. + */ +#define DEBUGFS_FSDATA_IS_SHORT_FOPS_BIT BIT(1) /* Access BITS */ #define DEBUGFS_ALLOW_API BIT(0) diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 0928a6c8ae1e..1f544d2ddc26 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -71,9 +71,63 @@ typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *); struct dentry *debugfs_lookup(const char *name, struct dentry *parent); -struct dentry *debugfs_create_file(const char *name, umode_t mode, - struct dentry *parent, void *data, - const struct file_operations *fops); +struct debugfs_short_fops { + ssize_t (*read)(struct file *, char __user *, size_t, loff_t *); + ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); + loff_t (*llseek) (struct file *, loff_t, int); +}; + +struct dentry *debugfs_create_file_full(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops); +struct dentry *debugfs_create_file_short(const char *name, umode_t mode, + struct dentry *parent, void *data, + const struct debugfs_short_fops *fops); + +/** + * debugfs_create_file - create a file in the debugfs filesystem + * @name: a pointer to a string containing the name of the file to create. + * @mode: the permission that the file should have. + * @parent: a pointer to the parent dentry for this file. This should be a + * directory dentry if set. If this parameter is NULL, then the + * file will be created in the root of the debugfs filesystem. + * @data: a pointer to something that the caller will want to get to later + * on. The inode.i_private pointer will point to this value on + * the open() call. + * @fops: a pointer to a struct file_operations or struct debugfs_short_fops that + * should be used for this file. + * + * This is the basic "create a file" function for debugfs. It allows for a + * wide range of flexibility in creating a file, or a directory (if you want + * to create a directory, the debugfs_create_dir() function is + * recommended to be used instead.) + * + * This function will return a pointer to a dentry if it succeeds. This + * pointer must be passed to the debugfs_remove() function when the file is + * to be removed (no automatic cleanup happens if your module is unloaded, + * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be + * returned. + * + * If debugfs is not enabled in the kernel, the value -%ENODEV will be + * returned. + * + * If fops points to a struct debugfs_short_fops, then simple_open() will be + * used for the open, and only read/write/llseek are supported and are proxied, + * so no module reference or release are needed. + * + * NOTE: it's expected that most callers should _ignore_ the errors returned + * by this function. Other debugfs functions handle the fact that the "dentry" + * passed to them could be an error and they don't crash in that case. + * Drivers should generally work fine even if debugfs fails to init anyway. + */ +#define debugfs_create_file(name, mode, parent, data, fops) \ + _Generic(fops, \ + const struct file_operations *: debugfs_create_file_full, \ + const struct debugfs_short_fops *: debugfs_create_file_short, \ + struct file_operations *: debugfs_create_file_full, \ + struct debugfs_short_fops *: debugfs_create_file_short) \ + (name, mode, parent, data, fops) + struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops); From patchwork Wed Oct 9 16:13:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 13828737 X-Patchwork-Delegate: johannes@sipsolutions.net Received: from sipsolutions.net (s3.sipsolutions.net [168.119.38.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 675A61F4FBB; Wed, 9 Oct 2024 16:13:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=168.119.38.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728490440; cv=none; b=PbvHrrDO/XZ+iPJFo9E32fh7gv7pUXNcHVHBJeo0DotYvMvbGMcyPE3K2qehrIC4EExaXYQvuqSv9+Tc0MN29XBnbZfKwJPfB40U3dWy3JeOoG2Oj8QJjpmwon1pKlIyjocDUh3g/wX63cQDZb4/z6niBw/x0wT7WNGPu6VUKzc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728490440; c=relaxed/simple; bh=Z+oket3xBCwJ0bvDL/ie0H2rhiygtkC+2PUg45tVk5E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K2WOOnFJtx9lO+mpfTmhJ7viVSOBLUEV2X+YU8CmRUnMfmHulrf6q4lrqzsanjt9btwu/myOOFTnlciaGE+He4GnLP2uY4lg4hgHY2GVSjd5aFOUQ+GUBqGs2SE4ZjSiDtwL4GQ7n6cl8fcWvv5TC1ddUcFmCVWwMklVhVwVOes= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sipsolutions.net; spf=pass smtp.mailfrom=sipsolutions.net; dkim=pass (2048-bit key) header.d=sipsolutions.net header.i=@sipsolutions.net header.b=WRxcBNZF; arc=none smtp.client-ip=168.119.38.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sipsolutions.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sipsolutions.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sipsolutions.net header.i=@sipsolutions.net header.b="WRxcBNZF" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Content-Type:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-To: Resent-Cc:Resent-Message-ID; bh=LDOOCDJ5R/2+L+RRdgZROWi2JRDZvD49wy3HbaKoYYM=; t=1728490438; x=1729700038; b=WRxcBNZF8QSzfqRPnDQHpnEXksl+PekqU2PfYFdzAa+wICu xQyu2PzVU8B0G/E/qpuHrzrRDcfIZRf3Gj3frf8HFbbykCvC/1ntWlWf1rozIh83i38xu2cMYDl7G Ow0PcdcN5tgY5bzInKl7gpkqTBcSfLPRqFQaRo3bEpocA4Mpcl1VS8KJAhyjPonJ7SkZ52lCGTBXI MDx0rxck3CAlYxf/LttBr+99jQsRu1NHBF3F1DZvNmvgjdpqjhETSYsdDhSuPcs/2DX/j7V9pkrv7 4mIWvdB6mNcA797S6yCnjQdxXVxbJrCR3Kj7+ngDWB9ayrMi4k3IjgEIS7Er2/iA==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.98) (envelope-from ) id 1syZJu-00000005EUI-1mfe; Wed, 09 Oct 2024 18:13:50 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , "Rafael J. Wysocki" , Alexander Viro , Johannes Berg Subject: [RFC PATCH 2/2] wifi: mac80211: convert debugfs files to short fops Date: Wed, 9 Oct 2024 18:13:40 +0200 Message-ID: <20241009181339.a97e7557a81f.I45657e6a8415d796ec95c95becc9efb377ee3be6@changeid> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241009181339.0b1a6eaef573.Ia80b55e934bbfc45ce0df42a3233d34b35508046@changeid> References: <20241009181339.0b1a6eaef573.Ia80b55e934bbfc45ce0df42a3233d34b35508046@changeid> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Johannes Berg Given the large size of the regular struct file_operations, save a lot of space with the newly added short fops for debugfs. Signed-off-by: Johannes Berg --- net/mac80211/debugfs.c | 27 +++++++++------------------ net/mac80211/debugfs_key.c | 9 +++------ net/mac80211/debugfs_netdev.c | 3 +-- net/mac80211/debugfs_sta.c | 9 +++------ net/mac80211/rate.c | 3 +-- net/mac80211/rate.h | 2 +- 6 files changed, 18 insertions(+), 35 deletions(-) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 02b5476a4376..c52e85829e71 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -42,9 +42,8 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \ } #define DEBUGFS_READONLY_FILE_OPS(name) \ -static const struct file_operations name## _ops = { \ +static const struct debugfs_short_fops name## _ops = { \ .read = name## _read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ }; @@ -142,10 +141,9 @@ static ssize_t aqm_write(struct file *file, return -EINVAL; } -static const struct file_operations aqm_ops = { +static const struct debugfs_short_fops aqm_ops = { .write = aqm_write, .read = aqm_read, - .open = simple_open, .llseek = default_llseek, }; @@ -194,10 +192,9 @@ static ssize_t airtime_flags_write(struct file *file, return count; } -static const struct file_operations airtime_flags_ops = { +static const struct debugfs_short_fops airtime_flags_ops = { .write = airtime_flags_write, .read = airtime_flags_read, - .open = simple_open, .llseek = default_llseek, }; @@ -225,9 +222,8 @@ static ssize_t aql_pending_read(struct file *file, buf, len); } -static const struct file_operations aql_pending_ops = { +static const struct debugfs_short_fops aql_pending_ops = { .read = aql_pending_read, - .open = simple_open, .llseek = default_llseek, }; @@ -305,10 +301,9 @@ static ssize_t aql_txq_limit_write(struct file *file, return count; } -static const struct file_operations aql_txq_limit_ops = { +static const struct debugfs_short_fops aql_txq_limit_ops = { .write = aql_txq_limit_write, .read = aql_txq_limit_read, - .open = simple_open, .llseek = default_llseek, }; @@ -355,10 +350,9 @@ static ssize_t aql_enable_write(struct file *file, const char __user *user_buf, return count; } -static const struct file_operations aql_enable_ops = { +static const struct debugfs_short_fops aql_enable_ops = { .write = aql_enable_write, .read = aql_enable_read, - .open = simple_open, .llseek = default_llseek, }; @@ -406,10 +400,9 @@ static ssize_t force_tx_status_write(struct file *file, return count; } -static const struct file_operations force_tx_status_ops = { +static const struct debugfs_short_fops force_tx_status_ops = { .write = force_tx_status_write, .read = force_tx_status_read, - .open = simple_open, .llseek = default_llseek, }; @@ -434,9 +427,8 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf, return count; } -static const struct file_operations reset_ops = { +static const struct debugfs_short_fops reset_ops = { .write = reset_write, - .open = simple_open, .llseek = noop_llseek, }; #endif @@ -623,9 +615,8 @@ static ssize_t stats_ ##name## _read(struct file *file, \ print_devstats_##name); \ } \ \ -static const struct file_operations stats_ ##name## _ops = { \ +static const struct debugfs_short_fops stats_ ##name## _ops = { \ .read = stats_ ##name## _read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ }; diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 7e54da508765..b3a64edea0f2 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -26,17 +26,15 @@ static ssize_t key_##name##_read(struct file *file, \ #define KEY_READ_X(name) KEY_READ(name, name, "0x%x\n") #define KEY_OPS(name) \ -static const struct file_operations key_ ##name## _ops = { \ +static const struct debugfs_short_fops key_ ##name## _ops = { \ .read = key_##name##_read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } #define KEY_OPS_W(name) \ -static const struct file_operations key_ ##name## _ops = { \ +static const struct debugfs_short_fops key_ ##name## _ops = { \ .read = key_##name##_read, \ .write = key_##name##_write, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } @@ -49,9 +47,8 @@ static const struct file_operations key_ ##name## _ops = { \ #define KEY_CONF_READ_D(name) KEY_CONF_READ(name, "%d\n") #define KEY_CONF_OPS(name) \ -static const struct file_operations key_ ##name## _ops = { \ +static const struct debugfs_short_fops key_ ##name## _ops = { \ .read = key_conf_##name##_read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 68596ef78b15..a9bc2fd59f55 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -221,10 +221,9 @@ static ssize_t ieee80211_if_fmt_##name( \ } #define _IEEE80211_IF_FILE_OPS(name, _read, _write) \ -static const struct file_operations name##_ops = { \ +static const struct debugfs_short_fops name##_ops = { \ .read = (_read), \ .write = (_write), \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 1e9389c49a57..a67a9d316008 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -30,17 +30,15 @@ static ssize_t sta_ ##name## _read(struct file *file, \ #define STA_READ_D(name, field) STA_READ(name, field, "%d\n") #define STA_OPS(name) \ -static const struct file_operations sta_ ##name## _ops = { \ +static const struct debugfs_short_fops sta_ ##name## _ops = { \ .read = sta_##name##_read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } #define STA_OPS_RW(name) \ -static const struct file_operations sta_ ##name## _ops = { \ +static const struct debugfs_short_fops sta_ ##name## _ops = { \ .read = sta_##name##_read, \ .write = sta_##name##_write, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } @@ -450,9 +448,8 @@ STA_OPS_RW(agg_status); /* link sta attributes */ #define LINK_STA_OPS(name) \ -static const struct file_operations link_sta_ ##name## _ops = { \ +static const struct debugfs_short_fops link_sta_ ##name## _ops = { \ .read = link_sta_##name##_read, \ - .open = simple_open, \ .llseek = generic_file_llseek, \ } diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 3dc9752188d5..d1577c88b932 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -229,9 +229,8 @@ static ssize_t rcname_read(struct file *file, char __user *userbuf, ref->ops->name, len); } -const struct file_operations rcname_ops = { +const struct debugfs_short_fops rcname_ops = { .read = rcname_read, - .open = simple_open, .llseek = default_llseek, }; #endif diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index d6190f10fe7c..d3f46e26453c 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h @@ -62,7 +62,7 @@ static inline void rate_control_add_sta_debugfs(struct sta_info *sta) #endif } -extern const struct file_operations rcname_ops; +extern const struct debugfs_short_fops rcname_ops; static inline void rate_control_add_debugfs(struct ieee80211_local *local) {