linux/net/sunrpc/xprtrdma/svc_rdma.c
<<
>>
Prefs
   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 and context caches */
  73struct kmem_cache *svc_rdma_map_cachep;
  74struct kmem_cache *svc_rdma_ctxt_cachep;
  75
  76/*
  77 * This function implements reading and resetting an atomic_t stat
  78 * variable through read/write to a proc file. Any write to the file
  79 * resets the associated statistic to zero. Any read returns it's
  80 * current value.
  81 */
  82static int read_reset_stat(ctl_table *table, int write,
  83                           void __user *buffer, size_t *lenp,
  84                           loff_t *ppos)
  85{
  86        atomic_t *stat = (atomic_t *)table->data;
  87
  88        if (!stat)
  89                return -EINVAL;
  90
  91        if (write)
  92                atomic_set(stat, 0);
  93        else {
  94                char str_buf[32];
  95                char *data;
  96                int len = snprintf(str_buf, 32, "%d\n", atomic_read(stat));
  97                if (len >= 32)
  98                        return -EFAULT;
  99                len = strlen(str_buf);
 100                if (*ppos > len) {
 101                        *lenp = 0;
 102                        return 0;
 103                }
 104                data = &str_buf[*ppos];
 105                len -= *ppos;
 106                if (len > *lenp)
 107                        len = *lenp;
 108                if (len && copy_to_user(buffer, str_buf, len))
 109                        return -EFAULT;
 110                *lenp = len;
 111                *ppos += len;
 112        }
 113        return 0;
 114}
 115
 116static struct ctl_table_header *svcrdma_table_header;
 117static ctl_table svcrdma_parm_table[] = {
 118        {
 119                .procname       = "max_requests",
 120                .data           = &svcrdma_max_requests,
 121                .maxlen         = sizeof(unsigned int),
 122                .mode           = 0644,
 123                .proc_handler   = &proc_dointvec_minmax,
 124                .strategy       = &sysctl_intvec,
 125                .extra1         = &min_max_requests,
 126                .extra2         = &max_max_requests
 127        },
 128        {
 129                .procname       = "max_req_size",
 130                .data           = &svcrdma_max_req_size,
 131                .maxlen         = sizeof(unsigned int),
 132                .mode           = 0644,
 133                .proc_handler   = &proc_dointvec_minmax,
 134                .strategy       = &sysctl_intvec,
 135                .extra1         = &min_max_inline,
 136                .extra2         = &max_max_inline
 137        },
 138        {
 139                .procname       = "max_outbound_read_requests",
 140                .data           = &svcrdma_ord,
 141                .maxlen         = sizeof(unsigned int),
 142                .mode           = 0644,
 143                .proc_handler   = &proc_dointvec_minmax,
 144                .strategy       = &sysctl_intvec,
 145                .extra1         = &min_ord,
 146                .extra2         = &max_ord,
 147        },
 148
 149        {
 150                .procname       = "rdma_stat_read",
 151                .data           = &rdma_stat_read,
 152                .maxlen         = sizeof(atomic_t),
 153                .mode           = 0644,
 154                .proc_handler   = &read_reset_stat,
 155        },
 156        {
 157                .procname       = "rdma_stat_recv",
 158                .data           = &rdma_stat_recv,
 159                .maxlen         = sizeof(atomic_t),
 160                .mode           = 0644,
 161                .proc_handler   = &read_reset_stat,
 162        },
 163        {
 164                .procname       = "rdma_stat_write",
 165                .data           = &rdma_stat_write,
 166                .maxlen         = sizeof(atomic_t),
 167                .mode           = 0644,
 168                .proc_handler   = &read_reset_stat,
 169        },
 170        {
 171                .procname       = "rdma_stat_sq_starve",
 172                .data           = &rdma_stat_sq_starve,
 173                .maxlen         = sizeof(atomic_t),
 174                .mode           = 0644,
 175                .proc_handler   = &read_reset_stat,
 176        },
 177        {
 178                .procname       = "rdma_stat_rq_starve",
 179                .data           = &rdma_stat_rq_starve,
 180                .maxlen         = sizeof(atomic_t),
 181                .mode           = 0644,
 182                .proc_handler   = &read_reset_stat,
 183        },
 184        {
 185                .procname       = "rdma_stat_rq_poll",
 186                .data           = &rdma_stat_rq_poll,
 187                .maxlen         = sizeof(atomic_t),
 188                .mode           = 0644,
 189                .proc_handler   = &read_reset_stat,
 190        },
 191        {
 192                .procname       = "rdma_stat_rq_prod",
 193                .data           = &rdma_stat_rq_prod,
 194                .maxlen         = sizeof(atomic_t),
 195                .mode           = 0644,
 196                .proc_handler   = &read_reset_stat,
 197        },
 198        {
 199                .procname       = "rdma_stat_sq_poll",
 200                .data           = &rdma_stat_sq_poll,
 201                .maxlen         = sizeof(atomic_t),
 202                .mode           = 0644,
 203                .proc_handler   = &read_reset_stat,
 204        },
 205        {
 206                .procname       = "rdma_stat_sq_prod",
 207                .data           = &rdma_stat_sq_prod,
 208                .maxlen         = sizeof(atomic_t),
 209                .mode           = 0644,
 210                .proc_handler   = &read_reset_stat,
 211        },
 212        {
 213                .ctl_name = 0,
 214        },
 215};
 216
 217static ctl_table svcrdma_table[] = {
 218        {
 219                .procname       = "svc_rdma",
 220                .mode           = 0555,
 221                .child          = svcrdma_parm_table
 222        },
 223        {
 224                .ctl_name = 0,
 225        },
 226};
 227
 228static ctl_table svcrdma_root_table[] = {
 229        {
 230                .ctl_name       = CTL_SUNRPC,
 231                .procname       = "sunrpc",
 232                .mode           = 0555,
 233                .child          = svcrdma_table
 234        },
 235        {
 236                .ctl_name = 0,
 237        },
 238};
 239
 240void svc_rdma_cleanup(void)
 241{
 242        dprintk("SVCRDMA Module Removed, deregister RPC RDMA transport\n");
 243        flush_scheduled_work();
 244        if (svcrdma_table_header) {
 245                unregister_sysctl_table(svcrdma_table_header);
 246                svcrdma_table_header = NULL;
 247        }
 248        svc_unreg_xprt_class(&svc_rdma_class);
 249        kmem_cache_destroy(svc_rdma_map_cachep);
 250        kmem_cache_destroy(svc_rdma_ctxt_cachep);
 251}
 252
 253int svc_rdma_init(void)
 254{
 255        dprintk("SVCRDMA Module Init, register RPC RDMA transport\n");
 256        dprintk("\tsvcrdma_ord      : %d\n", svcrdma_ord);
 257        dprintk("\tmax_requests     : %d\n", svcrdma_max_requests);
 258        dprintk("\tsq_depth         : %d\n",
 259                svcrdma_max_requests * RPCRDMA_SQ_DEPTH_MULT);
 260        dprintk("\tmax_inline       : %d\n", svcrdma_max_req_size);
 261        if (!svcrdma_table_header)
 262                svcrdma_table_header =
 263                        register_sysctl_table(svcrdma_root_table);
 264
 265        /* Create the temporary map cache */
 266        svc_rdma_map_cachep = kmem_cache_create("svc_rdma_map_cache",
 267                                                sizeof(struct svc_rdma_req_map),
 268                                                0,
 269                                                SLAB_HWCACHE_ALIGN,
 270                                                NULL);
 271        if (!svc_rdma_map_cachep) {
 272                printk(KERN_INFO "Could not allocate map cache.\n");
 273                goto err0;
 274        }
 275
 276        /* Create the temporary context cache */
 277        svc_rdma_ctxt_cachep =
 278                kmem_cache_create("svc_rdma_ctxt_cache",
 279                                  sizeof(struct svc_rdma_op_ctxt),
 280                                  0,
 281                                  SLAB_HWCACHE_ALIGN,
 282                                  NULL);
 283        if (!svc_rdma_ctxt_cachep) {
 284                printk(KERN_INFO "Could not allocate WR ctxt cache.\n");
 285                goto err1;
 286        }
 287
 288        /* Register RDMA with the SVC transport switch */
 289        svc_reg_xprt_class(&svc_rdma_class);
 290        return 0;
 291 err1:
 292        kmem_cache_destroy(svc_rdma_map_cachep);
 293 err0:
 294        unregister_sysctl_table(svcrdma_table_header);
 295        return -ENOMEM;
 296}
 297MODULE_AUTHOR("Tom Tucker <tom@opengridcomputing.com>");
 298MODULE_DESCRIPTION("SVC RDMA Transport");
 299MODULE_LICENSE("Dual BSD/GPL");
 300module_init(svc_rdma_init);
 301module_exit(svc_rdma_cleanup);
 302
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.