Commit 283e6f5a authored by Sergey Ryazanov's avatar Sergey Ryazanov Committed by Jakub Kicinski

net: wwan: make debugfs optional

Debugfs interface is optional for the regular modem use. Some distros
and users will want to disable this feature for security or kernel
size reasons. So add a configuration option that allows to completely
disable the debugfs interface of the WWAN devices.

A primary considered use case for this option was embedded firmwares.
For example, in OpenWrt, you can not completely disable debugfs, as a
lot of wireless stuff can only be configured and monitored with the
debugfs knobs. At the same time, reducing the size of a kernel and
modules is an essential task in the world of embedded software.
Disabling the WWAN and IOSM debugfs interfaces allows us to save 50K
(x86-64 build) of space for module storage. Not much, but already
considerable when you only have 16MB of storage.

So it is hard to just disable whole debugfs. Users need some fine
grained set of options to control which debugfs interface is important
and should be available and which is not.

The new configuration symbol is enabled by default and is hidden under
the EXPERT option. So a regular user would not be bothered by another
one configuration question. While an embedded distro maintainer will be
able to a little more reduce the final image size.
Signed-off-by: default avatarSergey Ryazanov <ryazanov.s.a@gmail.com>
Reviewed-by: default avatarLeon Romanovsky <leonro@nvidia.com>
Reviewed-by: default avatarLoic Poulain <loic.poulain@linaro.org>
Acked-by: default avatarM Chetan Kumar <m.chetan.kumar@intel.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent cf90098d
...@@ -16,6 +16,17 @@ config WWAN ...@@ -16,6 +16,17 @@ config WWAN
if WWAN if WWAN
config WWAN_DEBUGFS
bool "WWAN devices debugfs interface" if EXPERT
depends on DEBUG_FS
default y
help
Enables debugfs infrastructure for the WWAN core and device drivers.
If this option is selected, then you can find the debug interface
elements for each WWAN device in a directory that is corresponding to
the device name: debugfs/wwan/wwanX.
config WWAN_HWSIM config WWAN_HWSIM
tristate "Simulated WWAN device" tristate "Simulated WWAN device"
help help
...@@ -85,7 +96,7 @@ config IOSM ...@@ -85,7 +96,7 @@ config IOSM
tristate "IOSM Driver for Intel M.2 WWAN Device" tristate "IOSM Driver for Intel M.2 WWAN Device"
depends on INTEL_IOMMU depends on INTEL_IOMMU
select NET_DEVLINK select NET_DEVLINK
select RELAY select RELAY if WWAN_DEBUGFS
help help
This driver enables Intel M.2 WWAN Device communication. This driver enables Intel M.2 WWAN Device communication.
......
...@@ -21,7 +21,9 @@ iosm-y = \ ...@@ -21,7 +21,9 @@ iosm-y = \
iosm_ipc_mux_codec.o \ iosm_ipc_mux_codec.o \
iosm_ipc_devlink.o \ iosm_ipc_devlink.o \
iosm_ipc_flash.o \ iosm_ipc_flash.o \
iosm_ipc_coredump.o \ iosm_ipc_coredump.o
iosm-$(CONFIG_WWAN_DEBUGFS) += \
iosm_ipc_debugfs.o \ iosm_ipc_debugfs.o \
iosm_ipc_trace.o iosm_ipc_trace.o
......
...@@ -6,7 +6,12 @@ ...@@ -6,7 +6,12 @@
#ifndef IOSM_IPC_DEBUGFS_H #ifndef IOSM_IPC_DEBUGFS_H
#define IOSM_IPC_DEBUGFS_H #define IOSM_IPC_DEBUGFS_H
#ifdef CONFIG_WWAN_DEBUGFS
void ipc_debugfs_init(struct iosm_imem *ipc_imem); void ipc_debugfs_init(struct iosm_imem *ipc_imem);
void ipc_debugfs_deinit(struct iosm_imem *ipc_imem); void ipc_debugfs_deinit(struct iosm_imem *ipc_imem);
#else
static inline void ipc_debugfs_init(struct iosm_imem *ipc_imem) {}
static inline void ipc_debugfs_deinit(struct iosm_imem *ipc_imem) {}
#endif
#endif #endif
...@@ -274,7 +274,7 @@ static void ipc_imem_dl_skb_process(struct iosm_imem *ipc_imem, ...@@ -274,7 +274,7 @@ static void ipc_imem_dl_skb_process(struct iosm_imem *ipc_imem,
ipc_imem_sys_devlink_notify_rx(ipc_imem->ipc_devlink, ipc_imem_sys_devlink_notify_rx(ipc_imem->ipc_devlink,
skb); skb);
else if (ipc_is_trace_channel(ipc_imem, port_id)) else if (ipc_is_trace_channel(ipc_imem, port_id))
ipc_trace_port_rx(ipc_imem->trace, skb); ipc_trace_port_rx(ipc_imem, skb);
else else
wwan_port_rx(ipc_imem->ipc_port[port_id]->iosm_port, wwan_port_rx(ipc_imem->ipc_port[port_id]->iosm_port,
skb); skb);
......
...@@ -351,7 +351,9 @@ struct iosm_imem { ...@@ -351,7 +351,9 @@ struct iosm_imem {
struct iosm_mux *mux; struct iosm_mux *mux;
struct iosm_cdev *ipc_port[IPC_MEM_MAX_CHANNELS]; struct iosm_cdev *ipc_port[IPC_MEM_MAX_CHANNELS];
struct iosm_pcie *pcie; struct iosm_pcie *pcie;
#ifdef CONFIG_WWAN_DEBUGFS
struct iosm_trace *trace; struct iosm_trace *trace;
#endif
struct device *dev; struct device *dev;
enum ipc_mem_device_ipc_state ipc_requested_state; enum ipc_mem_device_ipc_state ipc_requested_state;
struct ipc_mem_channel channels[IPC_MEM_MAX_CHANNELS]; struct ipc_mem_channel channels[IPC_MEM_MAX_CHANNELS];
...@@ -381,7 +383,9 @@ struct iosm_imem { ...@@ -381,7 +383,9 @@ struct iosm_imem {
ev_mux_net_transmit_pending:1, ev_mux_net_transmit_pending:1,
reset_det_n:1, reset_det_n:1,
pcie_wake_n:1; pcie_wake_n:1;
#ifdef CONFIG_WWAN_DEBUGFS
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
#endif
}; };
/** /**
......
...@@ -17,11 +17,13 @@ ...@@ -17,11 +17,13 @@
/** /**
* ipc_trace_port_rx - Receive trace packet from cp and write to relay buffer * ipc_trace_port_rx - Receive trace packet from cp and write to relay buffer
* @ipc_trace: Pointer to the ipc trace data-struct * @ipc_imem: Pointer to iosm_imem structure
* @skb: Pointer to struct sk_buff * @skb: Pointer to struct sk_buff
*/ */
void ipc_trace_port_rx(struct iosm_trace *ipc_trace, struct sk_buff *skb) void ipc_trace_port_rx(struct iosm_imem *ipc_imem, struct sk_buff *skb)
{ {
struct iosm_trace *ipc_trace = ipc_imem->trace;
if (ipc_trace->ipc_rchan) if (ipc_trace->ipc_rchan)
relay_write(ipc_trace->ipc_rchan, skb->data, skb->len); relay_write(ipc_trace->ipc_rchan, skb->data, skb->len);
......
...@@ -45,6 +45,8 @@ struct iosm_trace { ...@@ -45,6 +45,8 @@ struct iosm_trace {
enum trace_ctrl_mode mode; enum trace_ctrl_mode mode;
}; };
#ifdef CONFIG_WWAN_DEBUGFS
static inline bool ipc_is_trace_channel(struct iosm_imem *ipc_mem, u16 chl_id) static inline bool ipc_is_trace_channel(struct iosm_imem *ipc_mem, u16 chl_id)
{ {
return ipc_mem->trace && ipc_mem->trace->chl_id == chl_id; return ipc_mem->trace && ipc_mem->trace->chl_id == chl_id;
...@@ -52,5 +54,21 @@ static inline bool ipc_is_trace_channel(struct iosm_imem *ipc_mem, u16 chl_id) ...@@ -52,5 +54,21 @@ static inline bool ipc_is_trace_channel(struct iosm_imem *ipc_mem, u16 chl_id)
struct iosm_trace *ipc_trace_init(struct iosm_imem *ipc_imem); struct iosm_trace *ipc_trace_init(struct iosm_imem *ipc_imem);
void ipc_trace_deinit(struct iosm_trace *ipc_trace); void ipc_trace_deinit(struct iosm_trace *ipc_trace);
void ipc_trace_port_rx(struct iosm_trace *ipc_trace, struct sk_buff *skb); void ipc_trace_port_rx(struct iosm_imem *ipc_imem, struct sk_buff *skb);
#else
static inline bool ipc_is_trace_channel(struct iosm_imem *ipc_mem, u16 chl_id)
{
return false;
}
static inline void ipc_trace_port_rx(struct iosm_imem *ipc_imem,
struct sk_buff *skb)
{
dev_kfree_skb(skb);
}
#endif
#endif #endif
...@@ -50,7 +50,9 @@ struct wwan_device { ...@@ -50,7 +50,9 @@ struct wwan_device {
atomic_t port_id; atomic_t port_id;
const struct wwan_ops *ops; const struct wwan_ops *ops;
void *ops_ctxt; void *ops_ctxt;
#ifdef CONFIG_WWAN_DEBUGFS
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
#endif
}; };
/** /**
...@@ -146,6 +148,7 @@ static struct wwan_device *wwan_dev_get_by_name(const char *name) ...@@ -146,6 +148,7 @@ static struct wwan_device *wwan_dev_get_by_name(const char *name)
return to_wwan_dev(dev); return to_wwan_dev(dev);
} }
#ifdef CONFIG_WWAN_DEBUGFS
struct dentry *wwan_get_debugfs_dir(struct device *parent) struct dentry *wwan_get_debugfs_dir(struct device *parent)
{ {
struct wwan_device *wwandev; struct wwan_device *wwandev;
...@@ -157,6 +160,7 @@ struct dentry *wwan_get_debugfs_dir(struct device *parent) ...@@ -157,6 +160,7 @@ struct dentry *wwan_get_debugfs_dir(struct device *parent)
return wwandev->debugfs_dir; return wwandev->debugfs_dir;
} }
EXPORT_SYMBOL_GPL(wwan_get_debugfs_dir); EXPORT_SYMBOL_GPL(wwan_get_debugfs_dir);
#endif
/* This function allocates and registers a new WWAN device OR if a WWAN device /* This function allocates and registers a new WWAN device OR if a WWAN device
* already exist for the given parent, it gets a reference and return it. * already exist for the given parent, it gets a reference and return it.
...@@ -166,7 +170,6 @@ EXPORT_SYMBOL_GPL(wwan_get_debugfs_dir); ...@@ -166,7 +170,6 @@ EXPORT_SYMBOL_GPL(wwan_get_debugfs_dir);
static struct wwan_device *wwan_create_dev(struct device *parent) static struct wwan_device *wwan_create_dev(struct device *parent)
{ {
struct wwan_device *wwandev; struct wwan_device *wwandev;
const char *wwandev_name;
int err, id; int err, id;
/* The 'find-alloc-register' operation must be protected against /* The 'find-alloc-register' operation must be protected against
...@@ -206,9 +209,11 @@ static struct wwan_device *wwan_create_dev(struct device *parent) ...@@ -206,9 +209,11 @@ static struct wwan_device *wwan_create_dev(struct device *parent)
goto done_unlock; goto done_unlock;
} }
wwandev_name = kobject_name(&wwandev->dev.kobj); #ifdef CONFIG_WWAN_DEBUGFS
wwandev->debugfs_dir = debugfs_create_dir(wwandev_name, wwandev->debugfs_dir =
wwan_debugfs_dir); debugfs_create_dir(kobject_name(&wwandev->dev.kobj),
wwan_debugfs_dir);
#endif
done_unlock: done_unlock:
mutex_unlock(&wwan_register_lock); mutex_unlock(&wwan_register_lock);
...@@ -240,7 +245,9 @@ static void wwan_remove_dev(struct wwan_device *wwandev) ...@@ -240,7 +245,9 @@ static void wwan_remove_dev(struct wwan_device *wwandev)
ret = device_for_each_child(&wwandev->dev, NULL, is_wwan_child); ret = device_for_each_child(&wwandev->dev, NULL, is_wwan_child);
if (!ret) { if (!ret) {
#ifdef CONFIG_WWAN_DEBUGFS
debugfs_remove_recursive(wwandev->debugfs_dir); debugfs_remove_recursive(wwandev->debugfs_dir);
#endif
device_unregister(&wwandev->dev); device_unregister(&wwandev->dev);
} else { } else {
put_device(&wwandev->dev); put_device(&wwandev->dev);
...@@ -1140,7 +1147,9 @@ static int __init wwan_init(void) ...@@ -1140,7 +1147,9 @@ static int __init wwan_init(void)
goto destroy; goto destroy;
} }
#ifdef CONFIG_WWAN_DEBUGFS
wwan_debugfs_dir = debugfs_create_dir("wwan", NULL); wwan_debugfs_dir = debugfs_create_dir("wwan", NULL);
#endif
return 0; return 0;
......
...@@ -171,6 +171,13 @@ int wwan_register_ops(struct device *parent, const struct wwan_ops *ops, ...@@ -171,6 +171,13 @@ int wwan_register_ops(struct device *parent, const struct wwan_ops *ops,
void wwan_unregister_ops(struct device *parent); void wwan_unregister_ops(struct device *parent);
#ifdef CONFIG_WWAN_DEBUGFS
struct dentry *wwan_get_debugfs_dir(struct device *parent); struct dentry *wwan_get_debugfs_dir(struct device *parent);
#else
static inline struct dentry *wwan_get_debugfs_dir(struct device *parent)
{
return ERR_PTR(-ENODEV);
}
#endif
#endif /* __WWAN_H */ #endif /* __WWAN_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment