3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  28  * Use is subject to license terms.
  29  */
  30 
  31 /*
  32  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
  33  */
  34 
  35 /*      Copyright (c) 1983, 1984, 1985,  1986, 1987, 1988, 1989 AT&T        */
  36 /*        All Rights Reserved   */
  37 
  38 /*
  39  * Portions of this source code were derived from Berkeley 4.3 BSD
  40  * under license from the Regents of the University of California.
  41  */
  42 
  43 /*
 
 
 202 #include <sys/file.h>
 203 #include <sys/systm.h>
 204 #include <sys/callb.h>
 205 #include <sys/vtrace.h>
 206 #include <sys/zone.h>
 207 #include <nfs/nfs.h>
 208 #include <sys/tsol/label_macro.h>
 209 
 210 /*
 211  * Defines for svc_poll()
 212  */
 213 #define SVC_EXPRTGONE ((SVCMASTERXPRT *)1)      /* Transport is closing */
 214 #define SVC_ETIMEDOUT ((SVCMASTERXPRT *)2)      /* Timeout */
 215 #define SVC_EINTR ((SVCMASTERXPRT *)3)          /* Interrupted by signal */
 216 
 217 /*
 218  * Default stack size for service threads.
 219  */
 220 #define DEFAULT_SVC_RUN_STKSIZE         (0)     /* default kernel stack */
 221 
 222 int    svc_default_stksize = DEFAULT_SVC_RUN_STKSIZE;
 223 
 224 /*
 225  * Default polling timeout for service threads.
 226  * Multiplied by hz when used.
 227  */
 228 #define DEFAULT_SVC_POLL_TIMEOUT        (5)     /* seconds */
 229 
 230 clock_t svc_default_timeout = DEFAULT_SVC_POLL_TIMEOUT;
 231 
 232 /*
 233  * Size of the `xprt-ready' queue.
 234  */
 235 #define DEFAULT_SVC_QSIZE               (256)   /* qnodes */
 236 
 237 size_t svc_default_qsize = DEFAULT_SVC_QSIZE;
 238 
 239 /*
 240  * Default limit for the number of service threads.
 241  */
 242 #define DEFAULT_SVC_MAXTHREADS          (INT16_MAX)
 243 
 244 int    svc_default_maxthreads = DEFAULT_SVC_MAXTHREADS;
 245 
 246 /*
 247  * Maximum number of requests from the same transport (in `drain' mode).
 248  */
 249 #define DEFAULT_SVC_MAX_SAME_XPRT       (8)
 250 
 251 int    svc_default_max_same_xprt = DEFAULT_SVC_MAX_SAME_XPRT;
 252 
 253 
 254 /*
 255  * Default `Redline' of non-detached threads.
 256  * Total number of detached and reserved threads in an RPC server
 257  * thread pool is limited to pool->p_maxthreads - svc_redline.
 258  */
 259 #define DEFAULT_SVC_REDLINE             (1)
 260 
 261 int    svc_default_redline = DEFAULT_SVC_REDLINE;
 262 
 263 /*
 264  * A node for the `xprt-ready' queue.
 265  * See below.
 266  */
 267 struct __svcxprt_qnode {
 268         __SVCXPRT_QNODE *q_next;
 269         SVCMASTERXPRT   *q_xprt;
 270 };
 271 
 
 279 
 280 /*
 281  * Debug variable to check for rdma based
 282  * transport startup and cleanup. Contorlled
 283  * through /etc/system. Off by default.
 284  */
 285 int rdma_check = 0;
 286 
 287 /*
 288  * This allows disabling flow control in svc_queuereq().
 289  */
 290 volatile int svc_flowcontrol_disable = 0;
 291 
 292 /*
 293  * Authentication parameters list.
 294  */
 295 static caddr_t rqcred_head;
 296 static kmutex_t rqcred_lock;
 297 
 298 /*
 299  * Pointers to transport specific `rele' routines in rpcmod (set from rpcmod).
 300  */
 301 void    (*rpc_rele)(queue_t *, mblk_t *, bool_t) = NULL;
 302 void    (*mir_rele)(queue_t *, mblk_t *, bool_t) = NULL;
 303 
 304 /* ARGSUSED */
 305 void
 306 rpc_rdma_rele(queue_t *q, mblk_t *mp, bool_t enable)
 307 {
 308 }
 309 void    (*rdma_rele)(queue_t *, mblk_t *, bool_t) = rpc_rdma_rele;
 310 
 311 
 312 /*
 313  * This macro picks which `rele' routine to use, based on the transport type.
 314  */
 315 #define RELE_PROC(xprt) \
 316         ((xprt)->xp_type == T_RDMA ? rdma_rele : \
 317         (((xprt)->xp_type == T_CLTS) ? rpc_rele : mir_rele))
 318 
 319 /*
 320  * If true, then keep quiet about version mismatch.
 321  * This macro is for broadcast RPC only. We have no broadcast RPC in
 322  * kernel now but one may define a flag in the transport structure
 323  * and redefine this macro.
 324  */
 325 #define version_keepquiet(xprt) (FALSE)
 326 
 327 /*
 328  * ZSD key used to retrieve zone-specific svc globals
 329  */
 330 static zone_key_t svc_zone_key;
 331 
 332 static void svc_callout_free(SVCMASTERXPRT *);
 333 static void svc_xprt_qinit(SVCPOOL *, size_t);
 334 static void svc_xprt_qdestroy(SVCPOOL *);
 335 static void svc_thread_creator(SVCPOOL *);
 336 static void svc_creator_signal(SVCPOOL *);
 337 static void svc_creator_signalexit(SVCPOOL *);
 338 static void svc_pool_unregister(struct svc_globals *, SVCPOOL *);
 339 static int svc_run(SVCPOOL *);
 
2370 
2371                 /*
2372                  * If the clone is marked detached then exit.
2373                  * The rpcmod slot has already been released
2374                  * when we detached this thread.
2375                  */
2376                 if (clone_xprt->xp_detached) {
2377                         svc_thread_exitdetached(pool, clone_xprt);
2378                         return (0);
2379                 }
2380 
2381                 /*
2382                  * Release our reference on the rpcmod
2383                  * slot attached to xp_wq->q_ptr.
2384                  */
2385                 mutex_enter(&xprt->xp_req_lock);
2386                 enable = xprt->xp_enable;
2387                 if (enable)
2388                         xprt->xp_enable = FALSE;
2389                 mutex_exit(&xprt->xp_req_lock);
2390                 (*RELE_PROC(xprt)) (clone_xprt->xp_wq, NULL, enable);
2391         }
2392         /* NOTREACHED */
2393 }
2394 
2395 /*
2396  * Flush any pending requests for the queue and
2397  * free the associated mblks.
2398  */
2399 void
2400 svc_queueclean(queue_t *q)
2401 {
2402         SVCMASTERXPRT *xprt = ((void **) q->q_ptr)[0];
2403         mblk_t *mp;
2404         SVCPOOL *pool;
2405 
2406         /*
2407          * clean up the requests
2408          */
2409         mutex_enter(&xprt->xp_req_lock);
2410         pool = xprt->xp_pool;
2411         while ((mp = xprt->xp_req_head) != NULL) {
2412                 /* remove the request from the list */
2413                 xprt->xp_req_head = mp->b_next;
2414                 mp->b_next = (mblk_t *)0;
2415                 (*RELE_PROC(xprt)) (xprt->xp_wq, mp, FALSE);
2416         }
2417 
2418         mutex_enter(&pool->p_req_lock);
2419         pool->p_reqs -= xprt->xp_reqs;
2420         pool->p_size -= xprt->xp_size;
2421         mutex_exit(&pool->p_req_lock);
2422 
2423         xprt->xp_reqs = 0;
2424         xprt->xp_size = 0;
2425         xprt->xp_full = FALSE;
2426         xprt->xp_enable = FALSE;
2427         mutex_exit(&xprt->xp_req_lock);
2428 }
2429 
2430 /*
2431  * This routine is called by rpcmod to inform kernel RPC that a
2432  * queue is closing. It is called after all the requests have been
2433  * picked up (that is after all the slots on the queue have
2434  * been released by kernel RPC). It is also guaranteed that no more
2435  * request will be delivered on this transport.
 
2712 
2713         /* Bookkeeping for this transport */
2714         mutex_enter(&xprt->xp_thread_lock);
2715         xprt->xp_threads--;
2716         xprt->xp_detached_threads++;
2717         mutex_exit(&xprt->xp_thread_lock);
2718 
2719         /* Bookkeeping for the pool */
2720         mutex_enter(&pool->p_thread_lock);
2721         pool->p_threads--;
2722         pool->p_reserved_threads--;
2723         pool->p_detached_threads++;
2724         mutex_exit(&pool->p_thread_lock);
2725 
2726         /* Release an rpcmod slot for this request */
2727         mutex_enter(&xprt->xp_req_lock);
2728         enable = xprt->xp_enable;
2729         if (enable)
2730                 xprt->xp_enable = FALSE;
2731         mutex_exit(&xprt->xp_req_lock);
2732         (*RELE_PROC(xprt)) (clone_xprt->xp_wq, NULL, enable);
2733 
2734         /* Mark the clone (thread) as detached */
2735         clone_xprt->xp_reserved = FALSE;
2736         clone_xprt->xp_detached = TRUE;
2737 
2738         return (NULL);
2739 }
2740 
2741 /*
2742  * This routine is responsible for extracting RDMA plugin master XPRT,
2743  * unregister from the SVCPOOL and initiate plugin specific cleanup.
2744  * It is passed a list/group of rdma transports as records which are
2745  * active in a given registered or unregistered kRPC thread pool. Its shuts
2746  * all active rdma transports in that pool. If the thread active on the trasport
2747  * happens to be last thread for that pool, it will signal the creater thread
2748  * to cleanup the pool and destroy the xprt in svc_queueclose()
2749  */
2750 void
2751 rdma_stop(rdma_xprt_group_t *rdma_xprts)
2752 {
 
 | 
 
 
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2012 Marcel Telka <marcel@telka.sk>
  24  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  26  */
  27 
  28 /*
  29  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  30  * Use is subject to license terms.
  31  */
  32 
  33 /*
  34  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
  35  */
  36 
  37 /*      Copyright (c) 1983, 1984, 1985,  1986, 1987, 1988, 1989 AT&T        */
  38 /*      All Rights Reserved     */
  39 
  40 /*
  41  * Portions of this source code were derived from Berkeley 4.3 BSD
  42  * under license from the Regents of the University of California.
  43  */
  44 
  45 /*
 
 
 204 #include <sys/file.h>
 205 #include <sys/systm.h>
 206 #include <sys/callb.h>
 207 #include <sys/vtrace.h>
 208 #include <sys/zone.h>
 209 #include <nfs/nfs.h>
 210 #include <sys/tsol/label_macro.h>
 211 
 212 /*
 213  * Defines for svc_poll()
 214  */
 215 #define SVC_EXPRTGONE ((SVCMASTERXPRT *)1)      /* Transport is closing */
 216 #define SVC_ETIMEDOUT ((SVCMASTERXPRT *)2)      /* Timeout */
 217 #define SVC_EINTR ((SVCMASTERXPRT *)3)          /* Interrupted by signal */
 218 
 219 /*
 220  * Default stack size for service threads.
 221  */
 222 #define DEFAULT_SVC_RUN_STKSIZE         (0)     /* default kernel stack */
 223 
 224 volatile int    svc_default_stksize = DEFAULT_SVC_RUN_STKSIZE;
 225 
 226 /*
 227  * Default polling timeout for service threads.
 228  * Multiplied by hz when used.
 229  */
 230 #define DEFAULT_SVC_POLL_TIMEOUT        (5)     /* seconds */
 231 
 232 clock_t svc_default_timeout = DEFAULT_SVC_POLL_TIMEOUT;
 233 
 234 /*
 235  * Size of the `xprt-ready' queue.
 236  */
 237 #define DEFAULT_SVC_QSIZE               (256)   /* qnodes */
 238 
 239 size_t svc_default_qsize = DEFAULT_SVC_QSIZE;
 240 
 241 /*
 242  * Default limit for the number of service threads.
 243  */
 244 #define DEFAULT_SVC_MAXTHREADS          (INT16_MAX)
 245 
 246 int    svc_default_maxthreads = DEFAULT_SVC_MAXTHREADS;
 247 
 248 /*
 249  * Maximum number of requests from the same transport (in `drain' mode).
 250  */
 251 #define DEFAULT_SVC_MAX_SAME_XPRT       (8)
 252 
 253 volatile int    svc_default_max_same_xprt = DEFAULT_SVC_MAX_SAME_XPRT;
 254 
 255 
 256 /*
 257  * Default `Redline' of non-detached threads.
 258  * Total number of detached and reserved threads in an RPC server
 259  * thread pool is limited to pool->p_maxthreads - svc_redline.
 260  */
 261 #define DEFAULT_SVC_REDLINE             (1)
 262 
 263 int    svc_default_redline = DEFAULT_SVC_REDLINE;
 264 
 265 /*
 266  * A node for the `xprt-ready' queue.
 267  * See below.
 268  */
 269 struct __svcxprt_qnode {
 270         __SVCXPRT_QNODE *q_next;
 271         SVCMASTERXPRT   *q_xprt;
 272 };
 273 
 
 281 
 282 /*
 283  * Debug variable to check for rdma based
 284  * transport startup and cleanup. Contorlled
 285  * through /etc/system. Off by default.
 286  */
 287 int rdma_check = 0;
 288 
 289 /*
 290  * This allows disabling flow control in svc_queuereq().
 291  */
 292 volatile int svc_flowcontrol_disable = 0;
 293 
 294 /*
 295  * Authentication parameters list.
 296  */
 297 static caddr_t rqcred_head;
 298 static kmutex_t rqcred_lock;
 299 
 300 /*
 301  * If true, then keep quiet about version mismatch.
 302  * This macro is for broadcast RPC only. We have no broadcast RPC in
 303  * kernel now but one may define a flag in the transport structure
 304  * and redefine this macro.
 305  */
 306 #define version_keepquiet(xprt) (FALSE)
 307 
 308 /*
 309  * ZSD key used to retrieve zone-specific svc globals
 310  */
 311 static zone_key_t svc_zone_key;
 312 
 313 static void svc_callout_free(SVCMASTERXPRT *);
 314 static void svc_xprt_qinit(SVCPOOL *, size_t);
 315 static void svc_xprt_qdestroy(SVCPOOL *);
 316 static void svc_thread_creator(SVCPOOL *);
 317 static void svc_creator_signal(SVCPOOL *);
 318 static void svc_creator_signalexit(SVCPOOL *);
 319 static void svc_pool_unregister(struct svc_globals *, SVCPOOL *);
 320 static int svc_run(SVCPOOL *);
 
 
2351 
2352                 /*
2353                  * If the clone is marked detached then exit.
2354                  * The rpcmod slot has already been released
2355                  * when we detached this thread.
2356                  */
2357                 if (clone_xprt->xp_detached) {
2358                         svc_thread_exitdetached(pool, clone_xprt);
2359                         return (0);
2360                 }
2361 
2362                 /*
2363                  * Release our reference on the rpcmod
2364                  * slot attached to xp_wq->q_ptr.
2365                  */
2366                 mutex_enter(&xprt->xp_req_lock);
2367                 enable = xprt->xp_enable;
2368                 if (enable)
2369                         xprt->xp_enable = FALSE;
2370                 mutex_exit(&xprt->xp_req_lock);
2371                 SVC_RELE(clone_xprt, NULL, enable);
2372         }
2373         /* NOTREACHED */
2374 }
2375 
2376 /*
2377  * Flush any pending requests for the queue and
2378  * free the associated mblks.
2379  */
2380 void
2381 svc_queueclean(queue_t *q)
2382 {
2383         SVCMASTERXPRT *xprt = ((void **) q->q_ptr)[0];
2384         mblk_t *mp;
2385         SVCPOOL *pool;
2386 
2387         /*
2388          * clean up the requests
2389          */
2390         mutex_enter(&xprt->xp_req_lock);
2391         pool = xprt->xp_pool;
2392         while ((mp = xprt->xp_req_head) != NULL) {
2393                 /* remove the request from the list */
2394                 xprt->xp_req_head = mp->b_next;
2395                 mp->b_next = (mblk_t *)0;
2396                 SVC_RELE(xprt, mp, FALSE);
2397         }
2398 
2399         mutex_enter(&pool->p_req_lock);
2400         pool->p_reqs -= xprt->xp_reqs;
2401         pool->p_size -= xprt->xp_size;
2402         mutex_exit(&pool->p_req_lock);
2403 
2404         xprt->xp_reqs = 0;
2405         xprt->xp_size = 0;
2406         xprt->xp_full = FALSE;
2407         xprt->xp_enable = FALSE;
2408         mutex_exit(&xprt->xp_req_lock);
2409 }
2410 
2411 /*
2412  * This routine is called by rpcmod to inform kernel RPC that a
2413  * queue is closing. It is called after all the requests have been
2414  * picked up (that is after all the slots on the queue have
2415  * been released by kernel RPC). It is also guaranteed that no more
2416  * request will be delivered on this transport.
 
2693 
2694         /* Bookkeeping for this transport */
2695         mutex_enter(&xprt->xp_thread_lock);
2696         xprt->xp_threads--;
2697         xprt->xp_detached_threads++;
2698         mutex_exit(&xprt->xp_thread_lock);
2699 
2700         /* Bookkeeping for the pool */
2701         mutex_enter(&pool->p_thread_lock);
2702         pool->p_threads--;
2703         pool->p_reserved_threads--;
2704         pool->p_detached_threads++;
2705         mutex_exit(&pool->p_thread_lock);
2706 
2707         /* Release an rpcmod slot for this request */
2708         mutex_enter(&xprt->xp_req_lock);
2709         enable = xprt->xp_enable;
2710         if (enable)
2711                 xprt->xp_enable = FALSE;
2712         mutex_exit(&xprt->xp_req_lock);
2713         SVC_RELE(clone_xprt, NULL, enable);
2714 
2715         /* Mark the clone (thread) as detached */
2716         clone_xprt->xp_reserved = FALSE;
2717         clone_xprt->xp_detached = TRUE;
2718 
2719         return (NULL);
2720 }
2721 
2722 /*
2723  * This routine is responsible for extracting RDMA plugin master XPRT,
2724  * unregister from the SVCPOOL and initiate plugin specific cleanup.
2725  * It is passed a list/group of rdma transports as records which are
2726  * active in a given registered or unregistered kRPC thread pool. Its shuts
2727  * all active rdma transports in that pool. If the thread active on the trasport
2728  * happens to be last thread for that pool, it will signal the creater thread
2729  * to cleanup the pool and destroy the xprt in svc_queueclose()
2730  */
2731 void
2732 rdma_stop(rdma_xprt_group_t *rdma_xprts)
2733 {
 
 |