kmem_cache_create(9f) 맨 페이지 - 윈디하나의 솔라나라

개요

섹션
맨 페이지 이름
검색(S)

kmem_cache_create(9f)

kmem_cache_create(9F)          Kernel Functions          kmem_cache_create(9F)

NAME
       kmem_cache_create,  kmem_cache_alloc,  kmem_cache_free,  kmem_cache_de‐
       stroy, kmem_cache_set_move - kernel memory cache allocator operations

SYNOPSIS
       #include <sys/types.h>
       #include <sys/kmem.h>

       kmem_cache_t *kmem_cache_create(char *name, size_t bufsize,
            size_t align, int (*constructor)(void *, void *, int),
            void (*destructor)(void *, void *), void (*reclaim)(void *),
            void *private, void *vmp, int cflags);


       void kmem_cache_destroy(kmem_cache_t *cp);


       void *kmem_cache_alloc(kmem_cache_t *cp, int kmflag);


       void kmem_cache_free(kmem_cache_t *cp, void *obj);


       void kmem_cache_set_move(kmem_cache_t *cp, kmem_cbrc_t (*move)(void *,
            void *, size_t *, void *));


        [Synopsis for callback functions:]


       int (*constructor)(void *buf, void *user_arg, int kmflags);


       void (*destructor)(void *buf, void *user_arg);


       kmem_cbrc_t (*move)(void *old, void *new, size_t bufsize,
            void *user_arg);

INTERFACE LEVEL
       Solaris DDI specific (Solaris DDI)

PARAMETERS
       The parameters for the kmem_cache_* functions are as follows:

       name           Descriptive name  of  a  kstat(9S)  structure  of  class
                      kmem_cache.  Names  longer  than 31 characters are trun‐
                      cated.


       bufsize        Size of the objects it manages.


       align          Required object alignment.


       constructor    Pointer to an object  constructor  function.  Parameters
                      are defined below.


       destructor     Pointer to an object destructor function. Parameters are
                      defined below.


       reclaim        Drivers should pass NULL.


       private        Pass-through argument for constructor/destructor.


       vmp            Drivers should pass NULL.


       cflags         Drivers must pass 0.


       kmflag         Possible flags are:

                      KM_SLEEP       Allow sleeping (blocking) until memory is
                                     available.


                      KM_NOSLEEP     Return  NULL immediately if memory is not
                                     available.


                      KM_PUSHPAGE    Allow the allocation to use reserved mem‐
                                     ory.



       obj            Pointer to the object allocated by kmem_cache_alloc().


       move           Pointer to an object relocation function. Parameters are
                      defined below.



       The parameters for the callback constructor function are as follows:

       void *buf         Pointer to the object to be constructed.


       void *user_arg    The   private   parameter   from    the    call    to
                         kmem_cache_create(); it is typically a pointer to the
                         soft-state structure.


       int kmflags       Propagated kmflag values.



       The parameters for the callback destructor function are as follows:

       void *buf         Pointer to the object to be deconstructed.


       void *user_arg    The    private    parameter    from   the   call   to
                         kmem_cache_create(); it is typically a pointer to the
                         soft-state structure.



       The parameters for the callback move() function are as follows:

       void *old         Pointer to the object to be moved.


       void *new         Pointer to the object that serves as the copy  desti‐
                         nation for the contents of the old parameter.


       size_t bufsize    Size of the object to be moved.


       void *user_arg    The    private    parameter    from   the   call   to
                         kmem_cache_create(); it is typically a pointer to the
                         soft-state structure.


DESCRIPTION
       In many cases, the cost of initializing and destroying  an  object  ex‐
       ceeds  the  cost of allocating and freeing memory for it. The functions
       described here address this condition.


       Object caching is a technique for dealing with objects that are:

           o      frequently allocated and freed, and


           o      have setup and initialization costs.



       The idea is to allow the allocator and its clients to cooperate to pre‐
       serve the invariant portion of  an  object's  initial  state,  or  con‐
       structed  state,  between uses, so it does not have to be destroyed and
       re-created every time the object is used. For example, an  object  con‐
       taining a mutex only needs to have mutex_init() applied once, the first
       time  the object is allocated. The object can then be freed and reallo‐
       cated many times without incurring the expense of  mutex_destroy()  and
       mutex_init()  each  time.  An  object's embedded locks, condition vari‐
       ables, reference counts, lists of other objects, and read-only data all
       generally qualify as constructed state. The  essential  requirement  is
       that  the  client must free the object (using kmem_cache_free()) in its
       constructed state. The allocator cannot enforce  this,  so  programming
       errors will lead to hard-to-find bugs.


       A  driver  should  call kmem_cache_create() at the time of _init(9E) or
       attach(9E), and call the corresponding kmem_cache_destroy() at the time
       of _fini(9E) or detach(9E).


       kmem_cache_create() creates a cache of objects, each  of  size  bufsize
       bytes,  aligned  on an align boundary. Drivers not requiring a specific
       alignment can pass 0. name identifies the cache for statistics and  de‐
       bugging.  constructor  and destructor convert plain memory into objects
       and back again; constructor can fail if it needs to allocate memory but
       cannot. private is a parameter passed to the constructor and destructor
       callbacks to support parameterized caches (for example, a pointer to an
       instance of the driver's soft-state structure).  To  facilitate  debug‐
       ging,  kmem_cache_create()  creates  a  kstat(9S)  structure  of  class
       kmem_cache and name name. It returns an opaque pointer  to  the  object
       cache.


       kmem_cache_alloc() gets an object from the cache. The object will be in
       its  constructed  state.  kmflag has either KM_SLEEP or KM_NOSLEEP set,
       indicating whether it is acceptable to wait for memory if none is  cur‐
       rently available.


       A  small  pool  of  reserved memory is available to allow the system to
       progress toward the goal of freeing additional memory while  in  a  low
       memory  situation.  The  KM_PUSHPAGE  flag enables use of this reserved
       memory pool on an allocation. This flag can be used by drivers that im‐
       plement strategy(9E) on memory allocations associated with a single I/O
       operation. The driver guarantees that the I/O operation  will  complete
       (or  timeout) and, on completion, that the memory will be returned. The
       KM_PUSHPAGE flag should be used only in kmem_cache_alloc()  calls.  All
       allocations from a given cache should be consistent in their use of the
       flag.  A  driver  that  adheres  to  these  restrictions  can guarantee
       progress in a low memory situation without resorting to complex private
       allocation and queuing schemes. If KM_PUSHPAGE is  specified,  KM_SLEEP
       can also be used without causing deadlock.


       kmem_cache_free() returns an object to the cache. The object must be in
       its constructed state.


       kmem_cache_destroy() destroys the cache and releases all associated re‐
       sources. All allocated objects must have been previously freed.


       kmem_cache_set_move()  registers a function that the allocator may call
       to move objects from sparsely allocated pages of  memory  so  that  the
       system  can reclaim pages that are tied up by the client. Since caching
       objects of the same size and type already makes severe memory  fragmen‐
       tation  unlikely,  there  is generally no need to register such a func‐
       tion. The idea is to make it possible to limit worst-case fragmentation
       in caches that exhibit a tendency to  become  highly  fragmented.  Only
       clients  that  allocate a mix of long- and short-lived objects from the
       same cache are prone to exhibit this tendency, making  them  candidates
       for a move() callback.


       The  move()  callback supplies the client with two addresses: the allo‐
       cated object that the allocator wants to move and a buffer selected  by
       the  allocator  for  the client to use as the copy destination. The new
       parameter is an allocated, constructed object ready to receive the con‐
       tents of the old parameter. The bufsize parameter supplies the size  of
       the  object,  in  case  a  single move function handles multiple caches
       whose objects differ only  in  size.  Finally,  the  private  parameter
       passed  to  the constructor and destructor is also passed to the move()
       callback.


       Only the client knows about its own data and when it is a good time  to
       move it. The client cooperates with the allocator to return unused mem‐
       ory  to the system, and the allocator accepts this help at the client's
       convenience. When asked to move an object, the client can respond  with
       any of the following:

         typedef enum kmem_cbrc {
                      KMEM_CBRC_YES,
                      KMEM_CBRC_NO,
                      KMEM_CBRC_LATER,
                      KMEM_CBRC_DONT_NEED,
                      KMEM_CBRC_DONT_KNOW
         } kmem_cbrc_t;





       The client must not explicitly free either of the objects passed to the
       move() callback, since the allocator wants to free them directly to the
       slab  layer  (bypassing the per-CPU magazine layer). The response tells
       the allocator which of the two object parameters to free:

       KMEM_CBRC_YES          The client moved the object; the allocator frees
                              the old parameter.


       KMEM_CBRC_NO           The client refused to move the object; the allo‐
                              cator frees the new parameter (the  unused  copy
                              destination).


       KMEM_CBRC_LATER        The  client  is using the object and cannot move
                              it now; the allocator frees  the  new  parameter
                              (the unused copy destination). The client should
                              use  KMEM_CBRC_LATER  instead of KMEM_CBRC_NO if
                              the object is likely to become movable soon.


       KMEM_CBRC_DONT_NEED    The client no longer needs the object; the allo‐
                              cator frees both the  old  and  new  parameters.
                              This  response is the client's opportunity to be
                              a model citizen and give back as much as it can.


       KMEM_CBRC_DONT_KNOW    The client does not know about  the  object  be‐
                              cause:


                              a)    the  client  has just allocated the object
                                    and has not yet put it wherever it expects
                                    to find known objects


                              b)    the client has  removed  the  object  from
                                    wherever  it expects to find known objects
                                    and is about to free the object


                              c)    the client has freed the object

                              In all of these cases above, the allocator frees
                              the new parameter (the unused copy  destination)
                              and  searches for the old parameter in the maga‐
                              zine layer. If the object is found,  it  is  re‐
                              moved  from  the magazine layer and freed to the
                              slab layer so that it will no longer tie  up  an
                              entire page of memory.



       Any  object  passed  to  the move() callback is guaranteed to have been
       touched only by the allocator or by the client. Because memory patterns
       applied by the allocator always set at least one of the two lowest  or‐
       der  bits, the bottom two bits of any pointer member (other than char *
       or short *, which may not be  8-byte  aligned  on  all  platforms)  are
       available  to  the client for marking cached objects that the client is
       about to free. This way, the client can recognize known objects in  the
       move() callback by the unmarked (valid) pointer value.


       If  the  client  refuses  to move an object with either KMEM_CBRC_NO or
       KMEM_CBRC_LATER, and that object later becomes movable, the client  can
       notify  the  allocator  by  calling  kmem_cache_move_notify(). Alterna‐
       tively, the client can simply wait for the allocator to call back again
       with the same object address. Responding KMEM_CRBC_NO even once or  re‐
       sponding  KMEM_CRBC_LATER  too many times for the same object makes the
       allocator less likely to call back again for that object.


       [Synopsis for notification function:]


       void kmem_cache_move_notify(kmem_cache_t *cp, void *obj);


       The parameters for the notification function are as follows:

       cp     Pointer to the object cache.


       obj    Pointer to the object that has become movable since  an  earlier
              refusal to move it.


CONTEXT
       Constructors  can be invoked during any call to kmem_cache_alloc(), and
       will run in that context. Similarly, destructors can be invoked  during
       any   call  to  kmem_cache_free(),  and  can  also  be  invoked  during
       kmem_cache_destroy(). Therefore, the functions that  a  constructor  or
       destructor  invokes  must  be appropriate in that context. Furthermore,
       the allocator may also call the constructor and destructor  on  objects
       still under its control without client involvement.


       kmem_cache_create()  and  kmem_cache_destroy()  must not be called from
       interrupt context. kmem_cache_create() can  also  block  for  available
       memory.


       kmem_cache_alloc()  can  be  called  from interrupt context only if the
       KM_NOSLEEP flag is set. It can be called from user  or  kernel  context
       with any valid flag.


       kmem_cache_free()  can  be  called from user, kernel, or interrupt con‐
       text.


       kmem_cache_set_move()   is   called   from   the   same   context    as
       kmem_cache_create(),  immediately  after kmem_cache_create() and before
       allocating any objects from the cache.


       The registered move() callback is always invoked  in  the  same  global
       callback  thread dedicated for move requests, guaranteeing that no mat‐
       ter how many clients register a move() function,  the  allocator  never
       tries to move more than one object at a time. Neither the allocator nor
       the  client can be assumed to know the object's whereabouts at the time
       of the callback.

EXAMPLES
       Example 1 Object Caching



       Consider the following data structure:


         struct foo {
             kmutex_t foo_lock;
             kcondvar_t foo_cv;
             struct bar *foo_barlist;
             int foo_refcnt;
             };






       Assume that a foo structure cannot be freed until  there  are  no  out‐
       standing  references to it (foo_refcnt == 0) and all of its pending bar
       events (whatever they are) have completed (foo_barlist  ==  NULL).  The
       life cycle of a dynamically allocated foo would be something like this:


         foo = kmem_alloc(sizeof (struct foo), KM_SLEEP);
         mutex_init(&foo->foo_lock, ...);
         cv_init(&foo->foo_cv, ...);
         foo->foo_refcnt = 0;
         foo->foo_barlist = NULL;
             use foo;
         ASSERT(foo->foo_barlist == NULL);
         ASSERT(foo->foo_refcnt == 0);
         cv_destroy(&foo->foo_cv);
         mutex_destroy(&foo->foo_lock);
         kmem_free(foo);






       Notice  that  between each use of a foo object we perform a sequence of
       operations that constitutes nothing but expensive overhead. All of this
       overhead (that is, everything other than use foo above) can  be  elimi‐
       nated by object caching.


         int
         foo_constructor(void *buf, void *arg, int tags)
         {
             struct foo *foo = buf;
             mutex_init(&foo->foo_lock, ...);
             cv_init(&foo->foo_cv, ...);
             foo->foo_refcnt = 0;
             foo->foo_barlist = NULL;
             return (0);
         }

         void
         foo_destructor(void *buf, void *arg)
         {
             struct foo *foo = buf;
             ASSERT(foo->foo_barlist == NULL);
             ASSERT(foo->foo_refcnt == 0);
             cv_destroy(&foo->foo_cv);
             mutex_destroy(&foo->foo_lock);
         }

         user_arg = ddi_get_soft_state(foo_softc, instance);
         (void) snprintf(buf, KSTAT_STRLEN, "foo%d_cache",
                 ddi_get_instance(dip));
         foo_cache = kmem_cache_create(buf,
                 sizeof (struct foo), 0,
                 foo_constructor, foo_destructor,
                 NULL, user_arg, 0);






       To allocate, use, and free a foo object:


         foo = kmem_cache_alloc(foo_cache, KM_SLEEP);
             use foo;
         kmem_cache_free(foo_cache, foo);






       This  makes  foo allocation fast, because the allocator will usually do
       nothing more than fetch an  already-constructed  foo  from  the  cache.
       foo_constructor and foo_destructor will be invoked only to populate and
       drain the cache, respectively.


       Example 2 Registering a Move Callback



       To register a move() callback:


         object_cache = kmem_cache_create(...);
         kmem_cache_set_move(object_cache, object_move);



RETURN VALUES
       If successful, the constructor function must return 0. If KM_NOSLEEP is
       set  and  memory  cannot be allocated without sleeping, the constructor
       must return -1.


       kmem_cache_create() returns a pointer to the allocated cache.


       If successful, kmem_cache_alloc() returns a pointer  to  the  allocated
       object.  If  KM_NOSLEEP  is  set and memory cannot be allocated without
       sleeping, kmem_cache_alloc() returns NULL.

ATTRIBUTES
       See attributes(7) for descriptions of the following attributes:

       tab() box; cw(2.75i) |cw(2.75i) lw(2.75i) |lw(2.75i) ATTRIBUTE  TYPEAT‐
       TRIBUTE VALUE _ Interface StabilityCommitted


SEE ALSO
       condvar(9F), kmem_alloc(9F), mutex(9F), kstat(9S)


       Writing Device Drivers in Oracle Solaris 11.4

       The Slab Allocator: An Object-Caching Kernel Memory Allocator, Bonwick,
       J.; USENIX Summer 1994 Technical Conference (1994).

           https://www.usenix.org/conference/usenix-summer-1994-technical-con‐
           ference/slab-allocator-object-caching-kernel


       Magazines and vmem: Extending the Slab Allocator to Many CPUs and Arbi‐
       trary Resources, Bonwick, J. and Adams, J.; USENIX 2001 Technical Con‐
       ference (2001).

           https://www.usenix.org/conference/2001-usenix-annual-technical-con‐
           ference/magazines-and-vmem-extending-slab-allocator-many


NOTES
       The constructor must be immediately reversible by the destructor, since
       the  allocator may call the constructor and destructor on objects still
       under its control at any time without client involvement.


       Do not bzero() from the constructor function. Instead  explicitly  ini‐
       tialize  the  fields  that  are  not  set in the constructor, after the
       kmem_cache_alloc() function.


       The constructor must respect the kmflags argument by forwarding  it  to
       allocations  made  inside the constructor, and must not ASSERT anything
       about the given flags.


       The user argument forwarded to the constructor  must  be  fully  opera‐
       tional before it is passed to the kmem_cache_create() function.


       Do  not put ASSERTs in the destructor that are not used for fields ini‐
       tialized in the constructor. Any such ASSERT can be put just before the
       kmem_cache_free() function.

Oracle Solaris 11.4               03 Nov 2016            kmem_cache_create(9F)
맨 페이지 내용의 저작권은 맨 페이지 작성자에게 있습니다.
RSS ATOM XHTML 5 CSS3