On 24/12/19 02:41, Chen Wandun wrote: > Use DEFINE_DEBUGFS_ATTRIBUTE rather than DEFINE_SIMPLE_ATTRIBUTE > for debugfs files. > > Semantic patch information: > Rationale: DEFINE_SIMPLE_ATTRIBUTE + debugfs_create_file() > imposes some significant overhead as compared to > DEFINE_DEBUGFS_ATTRIBUTE + debugfs_create_file_unsafe(). > > Signed-off-by: Chen Wandun <chenwandun@xxxxxxxxxx> This patch was sent probably already two or three times, and every time I've not been able to understand what is this significant overhead. With DEFINE_DEBUGFS_ATTRIBUTE: - the fops member is debugfs_open_proxy_file_operations, which calls replace_fops so that the fops->read member is debugfs_attr_read on the opened file - debugfs_attr_read does ret = debugfs_file_get(dentry); if (unlikely(ret)) return ret; ret = simple_attr_read(file, buf, len, ppos); debugfs_file_put(dentry); With DEFINE_SIMPLE_ATTRIBUTE: - the fops member is debugfs_full_proxy_open, and after __full_proxy_fops_init fops->read is initialized to full_proxy_read - full_proxy_read does r = debugfs_file_get(dentry); if (unlikely(r)) return r; real_fops = debugfs_real_fops(filp); r = real_fops->name(args); debugfs_file_put(dentry); return r; where real_fops->name is again just simple_attr_read. So the overhead is really just one kzalloc every time the file is opened. I could just apply the patch, but it wouldn't solve the main issue, which is that there is a function with a scary name ("debugfs_create_file_unsafe") that can be used in very common circumstances (with DEFINE_DEBUGFS_ATTRIBUTE. Therefore, we could instead fix the root cause and avoid using the scary API: - remove from the .cocci patch the change from debugfs_create_file to debugfs_create_file_unsafe. Only switch DEFINE_SIMPLE_ATTRIBUTE to DEFINE_DEBUGFS_ATTRIBUTE - change debugfs_create_file to automatically detect the "easy" case that does not need proxying of fops; something like this: const struct file_operations *proxy_fops; /* * Any struct file_operations defined by means of * DEFINE_DEBUGFS_ATTRIBUTE() is protected against file removals * and thus does not need proxying of read and write fops. */ if (!fops || (fops->llseek == no_llseek && ((!fops->read && !fops->read_iter) || fops->read == debugfs_attr_read) && ((!fops->write && !fops->write_iter) || fops->write == debugfs_attr_write) && !fops->poll && !fops->unlocked_ioctl) return debugfs_create_file_unsafe(name, mode, parent, data, fops); /* These are not supported by __full_proxy_fops_init. */ WARN_ON_ONCE(fops->read_iter || fops->write_iter); return __debugfs_create_file(name, mode, parent, data, &debugfs_full_proxy_file_operations, fops); CCing Nicolai Stange who first introduced debugfs_create_file_unsafe. Thanks, Paolo