The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/dmover/dmover_backend.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: dmover_backend.c,v 1.5 2003/04/26 04:44:18 briggs Exp $        */
    2 
    3 /*
    4  * Copyright (c) 2002 Wasabi Systems, Inc.
    5  * All rights reserved.
    6  *
    7  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed for the NetBSD Project by
   20  *      Wasabi Systems, Inc.
   21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
   22  *    or promote products derived from this software without specific prior
   23  *    written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
   29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   35  * POSSIBILITY OF SUCH DAMAGE.
   36  */
   37 
   38 /*
   39  * dmover_backend.c: Backend management functions for dmover-api.
   40  */
   41 
   42 #include <sys/cdefs.h>
   43 __KERNEL_RCSID(0, "$NetBSD: dmover_backend.c,v 1.5 2003/04/26 04:44:18 briggs Exp $");
   44 
   45 #include <sys/param.h>
   46 #include <sys/lock.h>
   47 #include <sys/systm.h>
   48 
   49 #include <dev/dmover/dmovervar.h>
   50 
   51 TAILQ_HEAD(, dmover_backend) dmover_backend_list;
   52 struct lock dmover_backend_list_lock;
   53 
   54 #define BACKEND_LIST_LOCK_READ()                                        \
   55 do {                                                                    \
   56         (void) spinlockmgr(&dmover_backend_list_lock, LK_SHARED, NULL); \
   57 } while (/*CONSTCOND*/0)
   58 
   59 #define BACKEND_LIST_UNLOCK_READ()                                      \
   60 do {                                                                    \
   61         (void) spinlockmgr(&dmover_backend_list_lock, LK_RELEASE, NULL);\
   62 } while (/*CONSTCOND*/0)
   63 
   64 #define BACKEND_LIST_LOCK_WRITE(s)                                      \
   65 do {                                                                    \
   66         (s) = splbio();                                                 \
   67         (void) spinlockmgr(&dmover_backend_list_lock, LK_EXCLUSIVE, NULL); \
   68 } while (/*CONSTCOND*/0)
   69 
   70 #define BACKEND_LIST_UNLOCK_WRITE(s)                                    \
   71 do {                                                                    \
   72         (void) spinlockmgr(&dmover_backend_list_lock, LK_RELEASE, NULL);\
   73         splx((s));                                                      \
   74 } while (/*CONSTCOND*/0)
   75 
   76 static int initialized;
   77 static struct simplelock initialized_slock = SIMPLELOCK_INITIALIZER;
   78 
   79 static void
   80 initialize(void)
   81 {
   82 
   83         simple_lock(&initialized_slock);
   84         if (__predict_true(initialized == 0)) {
   85                 TAILQ_INIT(&dmover_backend_list);
   86                 spinlockinit(&dmover_backend_list_lock, "dmbelk", 0);
   87 
   88                 /* Initialize the other bits of dmover. */
   89                 dmover_session_initialize();
   90                 dmover_request_initialize();
   91                 dmover_process_initialize();
   92 
   93                 initialized = 1;
   94         }
   95         simple_unlock(&initialized_slock);
   96 }
   97 
   98 /*
   99  * dmover_backend_register:     [back-end interface function]
  100  *
  101  *      Register a back-end with dmover-api.
  102  */
  103 void
  104 dmover_backend_register(struct dmover_backend *dmb)
  105 {
  106         int s;
  107 
  108         if (__predict_false(initialized == 0))
  109                 initialize();
  110 
  111         LIST_INIT(&dmb->dmb_sessions);
  112         dmb->dmb_nsessions = 0;
  113 
  114         TAILQ_INIT(&dmb->dmb_pendreqs);
  115         dmb->dmb_npendreqs = 0;
  116 
  117         BACKEND_LIST_LOCK_WRITE(s);
  118         TAILQ_INSERT_TAIL(&dmover_backend_list, dmb, dmb_list);
  119         BACKEND_LIST_UNLOCK_WRITE(s);
  120 }
  121 
  122 /*
  123  * dmover_backend_unregister:   [back-end interface function]
  124  *
  125  *      Un-register a back-end from dmover-api.
  126  */
  127 void
  128 dmover_backend_unregister(struct dmover_backend *dmb)
  129 {
  130         int s;
  131 
  132 #ifdef DIAGNOSTIC
  133         if (__predict_false(initialized == 0)) {
  134                 int croak;
  135 
  136                 simple_lock(&initialized_slock);
  137                 croak = (initialized == 0);
  138                 simple_unlock(&initialized_slock);
  139 
  140                 if (croak)
  141                         panic("dmover_backend_unregister: not initialized");
  142         }
  143 #endif
  144 
  145         /* XXX */
  146         if (dmb->dmb_nsessions)
  147                 panic("dmover_backend_unregister");
  148 
  149         BACKEND_LIST_LOCK_WRITE(s);
  150         TAILQ_REMOVE(&dmover_backend_list, dmb, dmb_list);
  151         BACKEND_LIST_UNLOCK_WRITE(s);
  152 }
  153 
  154 /*
  155  * dmover_backend_alloc:
  156  *
  157  *      Allocate and return a back-end on behalf of a session.
  158  */
  159 int
  160 dmover_backend_alloc(struct dmover_session *dses, const char *type)
  161 {
  162         struct dmover_backend *dmb, *best_dmb = NULL;
  163         const struct dmover_algdesc *algdesc, *best_algdesc = NULL;
  164 
  165         if (__predict_false(initialized == 0)) {
  166                 int fail;
  167 
  168                 simple_lock(&initialized_slock);
  169                 fail = (initialized == 0);
  170                 simple_unlock(&initialized_slock);
  171 
  172                 if (fail)
  173                         return (ESRCH);
  174         }
  175 
  176         BACKEND_LIST_LOCK_READ();
  177 
  178         /* First, find a back-end that can handle the session parts. */
  179         for (dmb = TAILQ_FIRST(&dmover_backend_list); dmb != NULL;
  180              dmb = TAILQ_NEXT(dmb, dmb_list)) {
  181                 /*
  182                  * First, check to see if the back-end supports the
  183                  * function we wish to perform.
  184                  */
  185                 algdesc = dmover_algdesc_lookup(dmb->dmb_algdescs,
  186                     dmb->dmb_nalgdescs, type);
  187                 if (algdesc == NULL)
  188                         continue;
  189 
  190                 if (best_dmb == NULL) {
  191                         best_dmb = dmb;
  192                         best_algdesc = algdesc;
  193                         continue;
  194                 }
  195 
  196                 /*
  197                  * XXX All the stuff from here on should be shot in
  198                  * XXX the head.  Instead, we should build a list
  199                  * XXX of candidates, and select the best back-end
  200                  * XXX when a request is scheduled for processing.
  201                  */
  202 
  203                 if (dmb->dmb_speed >= best_dmb->dmb_speed) {
  204                         /*
  205                          * If the current best match is slower than
  206                          * this back-end, then this one is the new
  207                          * best match.
  208                          */
  209                         if (dmb->dmb_speed > best_dmb->dmb_speed) {
  210                                 best_dmb = dmb;
  211                                 best_algdesc = algdesc;
  212                                 continue;
  213                         }
  214 
  215                         /*
  216                          * If this back-end has fewer sessions allocated
  217                          * to it than the current best match, then this
  218                          * one is now the best match.
  219                          */
  220                         if (best_dmb->dmb_nsessions > dmb->dmb_nsessions) {
  221                                 best_dmb = dmb;
  222                                 best_algdesc = algdesc;
  223                                 continue;
  224                         }
  225                 }
  226         }
  227         if (best_dmb == NULL) {
  228                 BACKEND_LIST_UNLOCK_READ();
  229                 return (ESRCH);
  230         }
  231 
  232         KASSERT(best_algdesc != NULL);
  233 
  234         /* Plug the back-end into the static (XXX) assignment. */
  235         dses->__dses_assignment.das_backend = best_dmb;
  236         dses->__dses_assignment.das_algdesc = best_algdesc;
  237 
  238         dses->dses_ninputs = best_algdesc->dad_ninputs;
  239 
  240         LIST_INSERT_HEAD(&best_dmb->dmb_sessions, dses, __dses_list);
  241         best_dmb->dmb_nsessions++;
  242 
  243         BACKEND_LIST_UNLOCK_READ();
  244 
  245         return (0);
  246 }
  247 
  248 /*
  249  * dmover_backend_release:
  250  *
  251  *      Release the back-end from the specified session.
  252  */
  253 void
  254 dmover_backend_release(struct dmover_session *dses)
  255 {
  256         struct dmover_backend *dmb;
  257 
  258         BACKEND_LIST_LOCK_READ();
  259 
  260         /* XXX Clear out the static assignment. */
  261         dmb = dses->__dses_assignment.das_backend;
  262         dses->__dses_assignment.das_backend = NULL;
  263         dses->__dses_assignment.das_algdesc = NULL;
  264 
  265         LIST_REMOVE(dses, __dses_list);
  266         dmb->dmb_nsessions--;
  267 
  268         BACKEND_LIST_UNLOCK_READ();
  269 }

Cache object: 10e8fee932a10fd58985360b8621eb0b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.