1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Shared Memory Communications over RDMA (SMC-R) and RoCE 4 * 5 * smc_sysctl.c: sysctl interface to SMC subsystem. 6 * 7 * Copyright (c) 2022, Alibaba Inc. 8 * 9 * Author: Tony Lu <tonylu@linux.alibaba.com> 10 * 11 */ 12 13 #include <linux/init.h> 14 #include <linux/sysctl.h> 15 #include <net/net_namespace.h> 16 17 #include "smc.h" 18 #include "smc_core.h" 19 #include "smc_llc.h" 20 #include "smc_sysctl.h" 21 22 static int min_sndbuf = SMC_BUF_MIN_SIZE; 23 static int min_rcvbuf = SMC_BUF_MIN_SIZE; 24 25 static struct ctl_table smc_table[] = { 26 { 27 .procname = "autocorking_size", 28 .data = &init_net.smc.sysctl_autocorking_size, 29 .maxlen = sizeof(unsigned int), 30 .mode = 0644, 31 .proc_handler = proc_douintvec, 32 }, 33 { 34 .procname = "smcr_buf_type", 35 .data = &init_net.smc.sysctl_smcr_buf_type, 36 .maxlen = sizeof(unsigned int), 37 .mode = 0644, 38 .proc_handler = proc_douintvec_minmax, 39 .extra1 = SYSCTL_ZERO, 40 .extra2 = SYSCTL_TWO, 41 }, 42 { 43 .procname = "smcr_testlink_time", 44 .data = &init_net.smc.sysctl_smcr_testlink_time, 45 .maxlen = sizeof(int), 46 .mode = 0644, 47 .proc_handler = proc_dointvec_jiffies, 48 }, 49 { 50 .procname = "wmem", 51 .data = &init_net.smc.sysctl_wmem, 52 .maxlen = sizeof(int), 53 .mode = 0644, 54 .proc_handler = proc_dointvec_minmax, 55 .extra1 = &min_sndbuf, 56 }, 57 { 58 .procname = "rmem", 59 .data = &init_net.smc.sysctl_rmem, 60 .maxlen = sizeof(int), 61 .mode = 0644, 62 .proc_handler = proc_dointvec_minmax, 63 .extra1 = &min_rcvbuf, 64 }, 65 { } 66 }; 67 68 int __net_init smc_sysctl_net_init(struct net *net) 69 { 70 struct ctl_table *table; 71 72 table = smc_table; 73 if (!net_eq(net, &init_net)) { 74 int i; 75 76 table = kmemdup(table, sizeof(smc_table), GFP_KERNEL); 77 if (!table) 78 goto err_alloc; 79 80 for (i = 0; i < ARRAY_SIZE(smc_table) - 1; i++) 81 table[i].data += (void *)net - (void *)&init_net; 82 } 83 84 net->smc.smc_hdr = register_net_sysctl(net, "net/smc", table); 85 if (!net->smc.smc_hdr) 86 goto err_reg; 87 88 net->smc.sysctl_autocorking_size = SMC_AUTOCORKING_DEFAULT_SIZE; 89 net->smc.sysctl_smcr_buf_type = SMCR_PHYS_CONT_BUFS; 90 net->smc.sysctl_smcr_testlink_time = SMC_LLC_TESTLINK_DEFAULT_TIME; 91 WRITE_ONCE(net->smc.sysctl_wmem, READ_ONCE(net->ipv4.sysctl_tcp_wmem[1])); 92 WRITE_ONCE(net->smc.sysctl_rmem, READ_ONCE(net->ipv4.sysctl_tcp_rmem[1])); 93 94 return 0; 95 96 err_reg: 97 if (!net_eq(net, &init_net)) 98 kfree(table); 99 err_alloc: 100 return -ENOMEM; 101 } 102 103 void __net_exit smc_sysctl_net_exit(struct net *net) 104 { 105 struct ctl_table *table; 106 107 table = net->smc.smc_hdr->ctl_table_arg; 108 unregister_net_sysctl_table(net->smc.smc_hdr); 109 if (!net_eq(net, &init_net)) 110 kfree(table); 111 } 112