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/norma/xmm_split.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 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1991 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie the
   24  * rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        xmm_split.c,v $
   29  * Revision 2.4  92/03/10  16:29:47  jsb
   30  *      Merged in norma branch changes as of NORMA_MK7.
   31  *      [92/03/09  12:51:54  jsb]
   32  * 
   33  * Revision 2.3.2.2  92/02/21  11:28:13  jsb
   34  *      Changed reply->mobj to reply->kobj. Discard reply in lock_completed.
   35  *      [92/02/16  18:24:34  jsb]
   36  * 
   37  *      Explicitly provide name parameter to xmm_decl macro.
   38  *      Changed debugging printf name and declaration.
   39  *      [92/02/16  14:25:05  jsb]
   40  * 
   41  *      Use new xmm_decl, and new memory_object_name and deallocation protocol.
   42  *      [92/02/09  14:17:57  jsb]
   43  * 
   44  * Revision 2.3.2.1  92/01/21  21:54:54  jsb
   45  *      De-linted. Supports new (dlb) memory object routines.
   46  *      Supports arbitrary reply ports to lock_request, etc.
   47  *      Converted mach_port_t (and port_t) to ipc_port_t.
   48  *      [92/01/20  17:30:57  jsb]
   49  * 
   50  * Revision 2.3  91/07/01  08:26:34  jsb
   51  *      Use zone for requests.
   52  *      [91/06/29  15:34:20  jsb]
   53  * 
   54  * Revision 2.2  91/06/17  15:48:40  jsb
   55  *      First checkin.
   56  *      [91/06/17  11:04:50  jsb]
   57  * 
   58  */
   59 /*
   60  *      File:   norma/xmm_split.c
   61  *      Author: Joseph S. Barrera III
   62  *      Date:   1991
   63  *
   64  *      Xmm layer to split multi-page lock_requests.
   65  */
   66 
   67 #ifdef  KERNEL
   68 #include <norma/xmm_obj.h>
   69 #include <mach/vm_param.h>
   70 #else   KERNEL
   71 #include <xmm_obj.h>
   72 #endif  KERNEL
   73 
   74 #define dprintf xmm_split_dprintf
   75 
   76 typedef struct request *request_t;
   77 
   78 #define REQUEST_NULL    ((request_t) 0)
   79 
   80 struct mobj {
   81         struct xmm_obj  obj;
   82         request_t       r_head;
   83         request_t       r_tail;
   84 };
   85 
   86 struct request {
   87         vm_offset_t     r_offset;
   88         vm_size_t       r_length;
   89         vm_offset_t     r_start;
   90         vm_size_t       r_count;
   91         vm_size_t       r_resid;
   92         request_t       r_next;
   93 };
   94 
   95 #undef  KOBJ
   96 #define KOBJ    ((struct mobj *) kobj)
   97 
   98 #define m_split_init                    m_interpose_init
   99 #define m_split_terminate               m_interpose_terminate
  100 #define m_split_deallocate              m_interpose_deallocate
  101 #define m_split_copy                    m_interpose_copy
  102 #define m_split_data_request            m_interpose_data_request
  103 #define m_split_data_unlock             m_interpose_data_unlock
  104 #define m_split_data_write              m_interpose_data_write
  105 #define m_split_supply_completed        m_interpose_supply_completed
  106 #define m_split_data_return             m_interpose_data_return
  107 #define m_split_change_completed        m_interpose_change_completed
  108 
  109 #define k_split_data_unavailable        k_interpose_data_unavailable
  110 #define k_split_get_attributes          k_interpose_get_attributes
  111 #define k_split_data_error              k_interpose_data_error
  112 #define k_split_set_ready               k_interpose_set_ready
  113 #define k_split_destroy                 k_interpose_destroy
  114 #define k_split_data_supply             k_interpose_data_supply
  115 
  116 xmm_decl(split, "split", sizeof(struct mobj));
  117 
  118 zone_t          xmm_split_request_zone;
  119 
  120 xmm_reply_t
  121 xmm_reply_allocate_reply(mobj, real_reply)
  122         xmm_obj_t mobj;
  123         xmm_reply_t real_reply;
  124 {
  125         kern_return_t kr;
  126         xmm_reply_t reply;
  127 
  128         if (real_reply == XMM_REPLY_NULL) {
  129                 return XMM_REPLY_NULL;
  130         }
  131         kr = xmm_reply_allocate(mobj, (ipc_port_t) real_reply, XMM_SPLIT_REPLY,
  132                                 &reply);
  133         if (kr != KERN_SUCCESS) {
  134                 panic("xmm_reply_allocate_mobj: xmm_reply_allocate: %d\n", kr);
  135         }
  136         return reply;
  137 }
  138 
  139 kern_return_t
  140 xmm_split_create(old_mobj, new_mobj)
  141         xmm_obj_t old_mobj;
  142         xmm_obj_t *new_mobj;
  143 {
  144         xmm_obj_t mobj;
  145         kern_return_t kr;
  146 
  147         kr = xmm_obj_allocate(&split_class, old_mobj, &mobj);
  148         if (kr != KERN_SUCCESS) {
  149                 return kr;
  150         }
  151         MOBJ->r_head = REQUEST_NULL;
  152         MOBJ->r_tail = REQUEST_NULL;
  153         *new_mobj = mobj;
  154         return KERN_SUCCESS;
  155 }
  156 
  157 k_split_lock_request(kobj, offset, length, should_clean, should_flush,
  158                      lock_value, reply)
  159         xmm_obj_t kobj;
  160         vm_offset_t offset;
  161         vm_size_t length;
  162         boolean_t should_clean;
  163         boolean_t should_flush;
  164         vm_prot_t lock_value;
  165         xmm_reply_t reply;
  166 {
  167         request_t r;
  168 
  169 #ifdef  lint
  170         K_LOCK_REQUEST(kobj, offset, length, should_clean, should_flush,
  171                        lock_value, reply);
  172 #endif  lint
  173         /*
  174          * If we don't have to split the request,
  175          * then just pass it through.
  176          */
  177         if (length == 0) {
  178                 return M_LOCK_COMPLETED(reply, offset, length);
  179         }
  180         if (length <= PAGE_SIZE) {
  181                 return K_LOCK_REQUEST(kobj, offset, length, should_clean,
  182                                       should_flush, lock_value, reply);
  183         }
  184         if (reply != XMM_REPLY_NULL) {
  185                 r = (request_t) zalloc(xmm_split_request_zone);
  186                 r->r_offset = offset;
  187                 r->r_length = length;
  188                 r->r_start = (offset + PAGE_SIZE - 1) / PAGE_SIZE;
  189                 r->r_count = (length + PAGE_SIZE - 1) / PAGE_SIZE;
  190                 r->r_resid = r->r_count;
  191                 r->r_next = REQUEST_NULL;
  192                 if (KOBJ->r_head) {
  193                         KOBJ->r_tail->r_next = r;
  194                 } else {
  195                         KOBJ->r_head = r;
  196                 }
  197                 KOBJ->r_tail = r;
  198                 dprintf("@r start=%d count=%d\n", r->r_start, r->r_count);
  199         }
  200         while (length > PAGE_SIZE) {
  201                 K_LOCK_REQUEST(kobj, offset, PAGE_SIZE, should_clean,
  202                                should_flush, lock_value,
  203                                xmm_reply_allocate_reply(kobj, reply));
  204                 offset += PAGE_SIZE;
  205                 length -= PAGE_SIZE;
  206         }
  207         if (length > 0) {
  208                 K_LOCK_REQUEST(kobj, offset, length, should_clean,
  209                                should_flush, lock_value,
  210                                xmm_reply_allocate_reply(kobj, reply));
  211         }
  212         /* XXX check return values above??? */
  213         return KERN_SUCCESS;
  214 }
  215 
  216 m_split_lock_completed(reply, offset, length)
  217         xmm_reply_t reply;
  218         vm_offset_t offset;
  219         vm_size_t length;       /* XXX ignored */
  220 {
  221         vm_offset_t start;
  222         request_t r, *rp, r_prev = REQUEST_NULL;
  223         xmm_obj_t kobj;
  224         xmm_reply_t real_reply;
  225 
  226 #ifdef  lint
  227         M_LOCK_COMPLETED(reply, offset, length);
  228 #endif  lint
  229         /*
  230          * If reply is not a private xmm_split reply, then
  231          * just pass it through.
  232          */
  233         if (reply->reply_to_type != XMM_SPLIT_REPLY) {
  234                 return M_LOCK_COMPLETED(reply, offset, length);
  235         }
  236 
  237         /*
  238          * Retrieve kobj and real reply from private reply,
  239          * and discard private reply.
  240          */
  241         kobj = reply->kobj;
  242         assert(kobj->class == &split_class);
  243         real_reply = (xmm_reply_t) reply->reply_to;
  244         xmm_reply_deallocate(reply);
  245 
  246         /*
  247          * Look for request structure.
  248          * XXX reply->reply_to really should be r, not reply.
  249          * XXX that would eliminate this stupid search.
  250          * XXX same thing goes for xmm_svm module.
  251          */
  252         start = (offset + PAGE_SIZE - 1) / PAGE_SIZE;
  253         dprintf("#r start=%d\n", start);
  254         for (rp = &KOBJ->r_head; r = *rp; rp = &r->r_next) {
  255                 dprintf(":r start=%d..%d resid=%d\n",
  256                        r->r_start, r->r_start + r->r_count - 1, r->r_resid);
  257                 if (start >= r->r_start && start < r->r_start + r->r_count) {
  258                         break;
  259                 }
  260                 r_prev = r;
  261         }
  262         if (r == REQUEST_NULL) {
  263                 panic("k_split_lock_completed: lost request\n");
  264         }
  265         dprintf("#r found\n");
  266 
  267         /*
  268          * If this is the reply that we are waiting for, then
  269          * send the real unsplit reply. Otherwise, just return.
  270          */
  271         if (--r->r_resid > 0) {
  272                 return KERN_SUCCESS;
  273         }
  274         if (r == KOBJ->r_tail) {
  275                 KOBJ->r_tail = r_prev;
  276         }
  277         *rp = r->r_next;
  278         M_LOCK_COMPLETED(real_reply, r->r_offset, r->r_length);
  279         zfree(xmm_split_request_zone, (vm_offset_t) r);
  280         return KERN_SUCCESS;
  281 }
  282 
  283 xmm_split_init()
  284 {
  285         xmm_split_request_zone = zinit(sizeof(struct request), 512*1024,
  286                                        sizeof(struct request), FALSE,
  287                                        "xmm.split.request");
  288 }
  289 
  290 #include <sys/varargs.h>
  291 
  292 int xmm_split_debug = 0;
  293 
  294 /* VARARGS */
  295 xmm_split_dprintf(fmt, va_alist)
  296         char *fmt;
  297         va_dcl
  298 {
  299         va_list listp;
  300 
  301         if (xmm_split_debug) {
  302                 va_start(listp);
  303                 printf(fmt, &listp);
  304                 va_end(listp);
  305         }
  306 }

Cache object: c7b2679faaed4785dbb0c0b4909b4e2a


[ 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.