svc_rdma.c revision ab96dddbedf4bb8a7a0fe44012efc1d99598c36f
1/* 2 * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the BSD-type 8 * license below: 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 17 * Redistributions in binary form must reproduce the above 18 * copyright notice, this list of conditions and the following 19 * disclaimer in the documentation and/or other materials provided 20 * with the distribution. 21 * 22 * Neither the name of the Network Appliance, Inc. nor the names of 23 * its contributors may be used to endorse or promote products 24 * derived from this software without specific prior written 25 * permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 * 39 * Author: Tom Tucker <tom@opengridcomputing.com> 40 */ 41#include <linux/module.h> 42#include <linux/init.h> 43#include <linux/fs.h> 44#include <linux/sysctl.h> 45#include <linux/sunrpc/clnt.h> 46#include <linux/sunrpc/sched.h> 47#include <linux/sunrpc/svc_rdma.h> 48 49#define RPCDBG_FACILITY RPCDBG_SVCXPRT 50 51/* RPC/RDMA parameters */ 52unsigned int svcrdma_ord = RPCRDMA_ORD; 53static unsigned int min_ord = 1; 54static unsigned int max_ord = 4096; 55unsigned int svcrdma_max_requests = RPCRDMA_MAX_REQUESTS; 56static unsigned int min_max_requests = 4; 57static unsigned int max_max_requests = 16384; 58unsigned int svcrdma_max_req_size = RPCRDMA_MAX_REQ_SIZE; 59static unsigned int min_max_inline = 4096; 60static unsigned int max_max_inline = 65536; 61 62atomic_t rdma_stat_recv; 63atomic_t rdma_stat_read; 64atomic_t rdma_stat_write; 65atomic_t rdma_stat_sq_starve; 66atomic_t rdma_stat_rq_starve; 67atomic_t rdma_stat_rq_poll; 68atomic_t rdma_stat_rq_prod; 69atomic_t rdma_stat_sq_poll; 70atomic_t rdma_stat_sq_prod; 71 72/* Temporary NFS request map cache */ 73struct kmem_cache *svc_rdma_map_cachep; 74 75/* 76 * This function implements reading and resetting an atomic_t stat 77 * variable through read/write to a proc file. Any write to the file 78 * resets the associated statistic to zero. Any read returns it's 79 * current value. 80 */ 81static int read_reset_stat(ctl_table *table, int write, 82 struct file *filp, void __user *buffer, size_t *lenp, 83 loff_t *ppos) 84{ 85 atomic_t *stat = (atomic_t *)table->data; 86 87 if (!stat) 88 return -EINVAL; 89 90 if (write) 91 atomic_set(stat, 0); 92 else { 93 char str_buf[32]; 94 char *data; 95 int len = snprintf(str_buf, 32, "%d\n", atomic_read(stat)); 96 if (len >= 32) 97 return -EFAULT; 98 len = strlen(str_buf); 99 if (*ppos > len) { 100 *lenp = 0; 101 return 0; 102 } 103 data = &str_buf[*ppos]; 104 len -= *ppos; 105 if (len > *lenp) 106 len = *lenp; 107 if (len && copy_to_user(buffer, str_buf, len)) 108 return -EFAULT; 109 *lenp = len; 110 *ppos += len; 111 } 112 return 0; 113} 114 115static struct ctl_table_header *svcrdma_table_header; 116static ctl_table svcrdma_parm_table[] = { 117 { 118 .procname = "max_requests", 119 .data = &svcrdma_max_requests, 120 .maxlen = sizeof(unsigned int), 121 .mode = 0644, 122 .proc_handler = &proc_dointvec_minmax, 123 .strategy = &sysctl_intvec, 124 .extra1 = &min_max_requests, 125 .extra2 = &max_max_requests 126 }, 127 { 128 .procname = "max_req_size", 129 .data = &svcrdma_max_req_size, 130 .maxlen = sizeof(unsigned int), 131 .mode = 0644, 132 .proc_handler = &proc_dointvec_minmax, 133 .strategy = &sysctl_intvec, 134 .extra1 = &min_max_inline, 135 .extra2 = &max_max_inline 136 }, 137 { 138 .procname = "max_outbound_read_requests", 139 .data = &svcrdma_ord, 140 .maxlen = sizeof(unsigned int), 141 .mode = 0644, 142 .proc_handler = &proc_dointvec_minmax, 143 .strategy = &sysctl_intvec, 144 .extra1 = &min_ord, 145 .extra2 = &max_ord, 146 }, 147 148 { 149 .procname = "rdma_stat_read", 150 .data = &rdma_stat_read, 151 .maxlen = sizeof(atomic_t), 152 .mode = 0644, 153 .proc_handler = &read_reset_stat, 154 }, 155 { 156 .procname = "rdma_stat_recv", 157 .data = &rdma_stat_recv, 158 .maxlen = sizeof(atomic_t), 159 .mode = 0644, 160 .proc_handler = &read_reset_stat, 161 }, 162 { 163 .procname = "rdma_stat_write", 164 .data = &rdma_stat_write, 165 .maxlen = sizeof(atomic_t), 166 .mode = 0644, 167 .proc_handler = &read_reset_stat, 168 }, 169 { 170 .procname = "rdma_stat_sq_starve", 171 .data = &rdma_stat_sq_starve, 172 .maxlen = sizeof(atomic_t), 173 .mode = 0644, 174 .proc_handler = &read_reset_stat, 175 }, 176 { 177 .procname = "rdma_stat_rq_starve", 178 .data = &rdma_stat_rq_starve, 179 .maxlen = sizeof(atomic_t), 180 .mode = 0644, 181 .proc_handler = &read_reset_stat, 182 }, 183 { 184 .procname = "rdma_stat_rq_poll", 185 .data = &rdma_stat_rq_poll, 186 .maxlen = sizeof(atomic_t), 187 .mode = 0644, 188 .proc_handler = &read_reset_stat, 189 }, 190 { 191 .procname = "rdma_stat_rq_prod", 192 .data = &rdma_stat_rq_prod, 193 .maxlen = sizeof(atomic_t), 194 .mode = 0644, 195 .proc_handler = &read_reset_stat, 196 }, 197 { 198 .procname = "rdma_stat_sq_poll", 199 .data = &rdma_stat_sq_poll, 200 .maxlen = sizeof(atomic_t), 201 .mode = 0644, 202 .proc_handler = &read_reset_stat, 203 }, 204 { 205 .procname = "rdma_stat_sq_prod", 206 .data = &rdma_stat_sq_prod, 207 .maxlen = sizeof(atomic_t), 208 .mode = 0644, 209 .proc_handler = &read_reset_stat, 210 }, 211 { 212 .ctl_name = 0, 213 }, 214}; 215 216static ctl_table svcrdma_table[] = { 217 { 218 .procname = "svc_rdma", 219 .mode = 0555, 220 .child = svcrdma_parm_table 221 }, 222 { 223 .ctl_name = 0, 224 }, 225}; 226 227static ctl_table svcrdma_root_table[] = { 228 { 229 .ctl_name = CTL_SUNRPC, 230 .procname = "sunrpc", 231 .mode = 0555, 232 .child = svcrdma_table 233 }, 234 { 235 .ctl_name = 0, 236 }, 237}; 238 239void svc_rdma_cleanup(void) 240{ 241 dprintk("SVCRDMA Module Removed, deregister RPC RDMA transport\n"); 242 if (svcrdma_table_header) { 243 unregister_sysctl_table(svcrdma_table_header); 244 svcrdma_table_header = NULL; 245 } 246 svc_unreg_xprt_class(&svc_rdma_class); 247 kmem_cache_destroy(svc_rdma_map_cachep); 248} 249 250int svc_rdma_init(void) 251{ 252 dprintk("SVCRDMA Module Init, register RPC RDMA transport\n"); 253 dprintk("\tsvcrdma_ord : %d\n", svcrdma_ord); 254 dprintk("\tmax_requests : %d\n", svcrdma_max_requests); 255 dprintk("\tsq_depth : %d\n", 256 svcrdma_max_requests * RPCRDMA_SQ_DEPTH_MULT); 257 dprintk("\tmax_inline : %d\n", svcrdma_max_req_size); 258 if (!svcrdma_table_header) 259 svcrdma_table_header = 260 register_sysctl_table(svcrdma_root_table); 261 262 /* Create the temporary map cache */ 263 svc_rdma_map_cachep = kmem_cache_create("svc_rdma_map_cache", 264 sizeof(struct svc_rdma_req_map), 265 0, 266 SLAB_HWCACHE_ALIGN, 267 NULL); 268 if (!svc_rdma_map_cachep) { 269 printk(KERN_INFO "Could not allocate map cache.\n"); 270 goto err; 271 } 272 273 /* Register RDMA with the SVC transport switch */ 274 svc_reg_xprt_class(&svc_rdma_class); 275 return 0; 276 277 err: 278 unregister_sysctl_table(svcrdma_table_header); 279 return -ENOMEM; 280} 281MODULE_AUTHOR("Tom Tucker <tom@opengridcomputing.com>"); 282MODULE_DESCRIPTION("SVC RDMA Transport"); 283MODULE_LICENSE("Dual BSD/GPL"); 284module_init(svc_rdma_init); 285module_exit(svc_rdma_cleanup); 286