summaryrefslogtreecommitdiffstats
path: root/net/sunrpc/sysctl.c
diff options
context:
space:
mode:
authorDanilo Krummrich <dakr@kernel.org>2026-08-13 18:52:04 +0200
committerDanilo Krummrich <dakr@kernel.org>2026-08-17 01:41:36 +0200
commitf146c7bc85a51f95c05e0f8173d484eb301ece78 (patch)
tree07296ae54ed6551492b0c609dc0f5463f61f89ca /net/sunrpc/sysctl.c
downloadlinux-stable-f146c7bc85a51f95c05e0f8173d484eb301ece78.tar.gz
linux-stable-f146c7bc85a51f95c05e0f8173d484eb301ece78.zip
PCI: Add pci_irq_type() to query the allocated interrupt typegrafted
Add a helper that returns PCI_IRQ_MSIX, PCI_IRQ_MSI, or PCI_IRQ_INTX based on the interrupt type the PCI core selected after pci_alloc_irq_vectors(). Several drivers already open-code this check against pdev->msix_enabled and pdev->msi_enabled, or even open code this helper [1]. A common helper avoids the duplication and keeps drivers from accessing the bitfield directly (see also [2]). Acked-by: Bjorn Helgaas <bhelgaas@google.com> Tested-by: John Hubbard <jhubbard@nvidia.com> Link: https://elixir.bootlin.com/linux/v7.1/source/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c#L196 [1] Inspired-by: John Hubbard <jhubbard@nvidia.com> Link: https://lore.kernel.org/all/DKKG2QM3YJYB.Z2H2B2UXJ75N@kernel.org/ [2] Reviewed-by: Gary Guo <gary@garyguo.net> Link: https://patch.msgid.link/20260813165234.620555-5-dakr@kernel.org [ Add missing pci_irq_type() stub for CONFIG_PCI=n. ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Diffstat (limited to 'net/sunrpc/sysctl.c')
-rw-r--r--net/sunrpc/sysctl.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
new file mode 100644
index 000000000..bdb587a72
--- /dev/null
+++ b/net/sunrpc/sysctl.c
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * linux/net/sunrpc/sysctl.c
+ *
+ * Sysctl interface to sunrpc module.
+ *
+ * I would prefer to register the sunrpc table below sys/net, but that's
+ * impossible at the moment.
+ */
+
+#include <linux/types.h>
+#include <linux/linkage.h>
+#include <linux/ctype.h>
+#include <linux/fs.h>
+#include <linux/sysctl.h>
+#include <linux/module.h>
+
+#include <linux/uaccess.h>
+#include <linux/sunrpc/types.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/stats.h>
+#include <linux/sunrpc/svc_xprt.h>
+
+#include "netns.h"
+
+/*
+ * Declare the debug flags here
+ */
+unsigned int rpc_debug;
+EXPORT_SYMBOL_GPL(rpc_debug);
+
+unsigned int nfs_debug;
+EXPORT_SYMBOL_GPL(nfs_debug);
+
+unsigned int nfsd_debug;
+EXPORT_SYMBOL_GPL(nfsd_debug);
+
+unsigned int nlm_debug;
+EXPORT_SYMBOL_GPL(nlm_debug);
+
+#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
+
+static int proc_do_xprt(const struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ char tmpbuf[256];
+ ssize_t len;
+
+ if (write || *ppos) {
+ *lenp = 0;
+ return 0;
+ }
+ len = svc_print_xprts(tmpbuf, sizeof(tmpbuf));
+ len = memory_read_from_buffer(buffer, *lenp, ppos, tmpbuf, len);
+
+ if (len < 0) {
+ *lenp = 0;
+ return -EINVAL;
+ }
+ *lenp = len;
+ return 0;
+}
+
+static int
+proc_dodebug(const struct ctl_table *table, int write, void *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ char tmpbuf[20], *s = NULL;
+ char *p;
+ unsigned int value;
+ size_t left, len;
+
+ if ((*ppos && !write) || !*lenp) {
+ *lenp = 0;
+ return 0;
+ }
+
+ left = *lenp;
+
+ if (write) {
+ p = buffer;
+ while (left && isspace(*p)) {
+ left--;
+ p++;
+ }
+ if (!left)
+ goto done;
+
+ if (left > sizeof(tmpbuf) - 1)
+ return -EINVAL;
+ memcpy(tmpbuf, p, left);
+ tmpbuf[left] = '\0';
+
+ value = simple_strtol(tmpbuf, &s, 0);
+ if (s) {
+ left -= (s - tmpbuf);
+ if (left && !isspace(*s))
+ return -EINVAL;
+ while (left && isspace(*s)) {
+ left--;
+ s++;
+ }
+ } else
+ left = 0;
+ *(unsigned int *) table->data = value;
+ /* Display the RPC tasks on writing to rpc_debug */
+ if (strcmp(table->procname, "rpc_debug") == 0)
+ rpc_show_tasks(&init_net);
+ } else {
+ len = sprintf(tmpbuf, "0x%04x", *(unsigned int *) table->data);
+ if (len > left)
+ len = left;
+ memcpy(buffer, tmpbuf, len);
+ if ((left -= len) > 0) {
+ *((char *)buffer + len) = '\n';
+ left--;
+ }
+ }
+
+done:
+ *lenp -= left;
+ *ppos += *lenp;
+ return 0;
+}
+
+static struct ctl_table_header *sunrpc_table_header;
+
+static struct ctl_table debug_table[] = {
+ {
+ .procname = "rpc_debug",
+ .data = &rpc_debug,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dodebug
+ },
+ {
+ .procname = "nfs_debug",
+ .data = &nfs_debug,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dodebug
+ },
+ {
+ .procname = "nfsd_debug",
+ .data = &nfsd_debug,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dodebug
+ },
+ {
+ .procname = "nlm_debug",
+ .data = &nlm_debug,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dodebug
+ },
+ {
+ .procname = "transports",
+ .maxlen = 256,
+ .mode = 0444,
+ .proc_handler = proc_do_xprt,
+ },
+};
+
+void
+rpc_register_sysctl(void)
+{
+ if (!sunrpc_table_header)
+ sunrpc_table_header = register_sysctl("sunrpc", debug_table);
+}
+
+void
+rpc_unregister_sysctl(void)
+{
+ if (sunrpc_table_header) {
+ unregister_sysctl_table(sunrpc_table_header);
+ sunrpc_table_header = NULL;
+ }
+}
+#endif