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 static int max_sndbuf = INT_MAX / 2; 25 static int max_rcvbuf = INT_MAX / 2; 26 static const int net_smc_wmem_init = (64 * 1024); 27 static const int net_smc_rmem_init = (64 * 1024); 28 29 static struct ctl_table smc_table[] = { 30 { 31 .procname = "autocorking_size", 32 .data = &init_net.smc.sysctl_autocorking_size, 33 .maxlen = sizeof(unsigned int), 34 .mode = 0644, 35 .proc_handler = proc_douintvec, 36 }, 37 { 38 .procname = "smcr_buf_type", 39 .data = &init_net.smc.sysctl_smcr_buf_type, 40 .maxlen = sizeof(unsigned int), 41 .mode = 0644, 42 .proc_handler = proc_douintvec_minmax, 43 .extra1 = SYSCTL_ZERO, 44 .extra2 = SYSCTL_TWO, 45 }, 46 { 47 .procname = "smcr_testlink_time", 48 .data = &init_net.smc.sysctl_smcr_testlink_time, 49 .maxlen = sizeof(int), 50 .mode = 0644, 51 .proc_handler = proc_dointvec_jiffies, 52 }, 53 { 54 .procname = "wmem", 55 .data = &init_net.smc.sysctl_wmem, 56 .maxlen = sizeof(int), 57 .mode = 0644, 58 .proc_handler = proc_dointvec_minmax, 59 .extra1 = &min_sndbuf, 60 .extra2 = &max_sndbuf, 61 }, 62 { 63 .procname = "rmem", 64 .data = &init_net.smc.sysctl_rmem, 65 .maxlen = sizeof(int), 66 .mode = 0644, 67 .proc_handler = proc_dointvec_minmax, 68 .extra1 = &min_rcvbuf, 69 .extra2 = &max_rcvbuf, 70 }, 71 { } 72 }; 73 74 int __net_init smc_sysctl_net_init(struct net *net) 75 { 76 struct ctl_table *table; 77 78 table = smc_table; 79 if (!net_eq(net, &init_net)) { 80 int i; 81 82 table = kmemdup(table, sizeof(smc_table), GFP_KERNEL); 83 if (!table) 84 goto err_alloc; 85 86 for (i = 0; i < ARRAY_SIZE(smc_table) - 1; i++) 87 table[i].data += (void *)net - (void *)&init_net; 88 } 89 90 net->smc.smc_hdr = register_net_sysctl_sz(net, "net/smc", table, 91 ARRAY_SIZE(smc_table)); 92 if (!net->smc.smc_hdr) 93 goto err_reg; 94 95 net->smc.sysctl_autocorking_size = SMC_AUTOCORKING_DEFAULT_SIZE; 96 net->smc.sysctl_smcr_buf_type = SMCR_PHYS_CONT_BUFS; 97 net->smc.sysctl_smcr_testlink_time = SMC_LLC_TESTLINK_DEFAULT_TIME; 98 WRITE_ONCE(net->smc.sysctl_wmem, net_smc_wmem_init); 99 WRITE_ONCE(net->smc.sysctl_rmem, net_smc_rmem_init); 100 101 return 0; 102 103 err_reg: 104 if (!net_eq(net, &init_net)) 105 kfree(table); 106 err_alloc: 107 return -ENOMEM; 108 } 109 110 void __net_exit smc_sysctl_net_exit(struct net *net) 111 { 112 struct ctl_table *table; 113 114 table = net->smc.smc_hdr->ctl_table_arg; 115 unregister_net_sysctl_table(net->smc.smc_hdr); 116 if (!net_eq(net, &init_net)) 117 kfree(table); 118 } 119