| Commit | Line | Data |
|---|---|---|
| 4860553a JH |
1 | /* |
| 2 | * Copyright (c) 1998 David Greenman. All rights reserved. | |
| 3 | * | |
| 4 | * Redistribution and use in source and binary forms, with or without | |
| 5 | * modification, are permitted provided that the following conditions | |
| 6 | * are met: | |
| 7 | * 1. Redistributions of source code must retain the above copyright | |
| 8 | * notice, this list of conditions and the following disclaimer. | |
| 9 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 10 | * notice, this list of conditions and the following disclaimer in the | |
| 11 | * documentation and/or other materials provided with the distribution. | |
| 12 | * | |
| 13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
| 14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 16 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
| 17 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 19 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 20 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 23 | * SUCH DAMAGE. | |
| 24 | * | |
| ba39e2e0 | 25 | * $DragonFly: src/sys/kern/kern_sfbuf.c,v 1.15 2007/04/30 07:18:53 dillon Exp $ |
| 4860553a JH |
26 | */ |
| 27 | ||
| 28 | #include <sys/param.h> | |
| 29 | #include <sys/types.h> | |
| 30 | #include <sys/systm.h> | |
| 31 | #include <sys/kernel.h> | |
| 32 | #include <sys/malloc.h> | |
| 4860553a | 33 | #include <sys/sfbuf.h> |
| 382a4dbd | 34 | #include <sys/ref.h> |
| 5c5185ae SG |
35 | #include <sys/objcache.h> |
| 36 | ||
| 37 | #include <cpu/lwbuf.h> | |
| 38 | ||
| 4860553a JH |
39 | #include <vm/vm.h> |
| 40 | #include <vm/vm_extern.h> | |
| 41 | #include <vm/vm_kern.h> | |
| 42 | #include <vm/vm_page.h> | |
| 43 | #include <vm/pmap.h> | |
| 44 | ||
| 45 | static void sf_buf_init(void *arg); | |
| ba39e2e0 | 46 | SYSINIT(sock_sf, SI_BOOT2_MACHDEP, SI_ORDER_ANY, sf_buf_init, NULL) |
| 4860553a JH |
47 | |
| 48 | LIST_HEAD(sf_buf_list, sf_buf); | |
| 49 | ||
| 5c5185ae | 50 | static struct objcache *sf_buf_cache; |
| ad9e1baa | 51 | |
| 5c5185ae SG |
52 | MALLOC_DEFINE(M_SFBUF, "sfbuf", "Sendfile buffer structures"); |
| 53 | struct objcache_malloc_args sf_buf_malloc_args = { sizeof(struct sf_buf), M_SFBUF }; | |
| 4860553a | 54 | |
| 4860553a | 55 | |
| 5c5185ae SG |
56 | static boolean_t |
| 57 | sf_buf_cache_ctor(void *obj, void *pdata, int ocflags) | |
| b89e3239 | 58 | { |
| 5c5185ae | 59 | struct sf_buf *sf = (struct sf_buf *)obj; |
| b89e3239 | 60 | |
| 5c5185ae | 61 | sf->lwbuf = NULL; |
| 382a4dbd | 62 | kref_init(&sf->ref, 0); |
| 5c5185ae SG |
63 | |
| 64 | return (TRUE); | |
| b89e3239 MD |
65 | } |
| 66 | ||
| 4860553a | 67 | /* |
| 5c5185ae | 68 | * Init objcache of sf_bufs (sendfile(2) or "super-fast" if you prefer. :-)) |
| 4860553a JH |
69 | */ |
| 70 | static void | |
| 71 | sf_buf_init(void *arg) | |
| 72 | { | |
| 5c5185ae SG |
73 | sf_buf_cache = objcache_create("sf_buf", 0, 0, |
| 74 | sf_buf_cache_ctor, NULL, NULL, | |
| 75 | objcache_malloc_alloc, objcache_malloc_free, | |
| 76 | &sf_buf_malloc_args); | |
| 4860553a JH |
77 | } |
| 78 | ||
| 79 | /* | |
| 5c5185ae | 80 | * Acquire an sf_buf reference for a vm_page. |
| 4860553a JH |
81 | */ |
| 82 | struct sf_buf * | |
| 5c5185ae | 83 | sf_buf_alloc(struct vm_page *m) |
| 4860553a | 84 | { |
| 4860553a | 85 | struct sf_buf *sf; |
| 5c5185ae SG |
86 | |
| 87 | if ((sf = objcache_get(sf_buf_cache, M_WAITOK)) == NULL) | |
| 88 | goto done; | |
| 89 | ||
| 7a683a24 | 90 | if ((sf->lwbuf = lwbuf_alloc(m, &sf->lwbuf_cache)) == NULL) { |
| 5c5185ae SG |
91 | objcache_put(sf_buf_cache, sf); |
| 92 | sf = NULL; | |
| 93 | goto done; | |
| 4860553a JH |
94 | } |
| 95 | ||
| 96 | /* | |
| 5c5185ae | 97 | * Force invalidation of the TLB entry on all CPU's |
| 4860553a | 98 | */ |
| 5c5185ae SG |
99 | lwbuf_set_global(sf->lwbuf); |
| 100 | ||
| 382a4dbd | 101 | kref_init(&sf->ref, 1); |
| 5c5185ae | 102 | |
| 4860553a | 103 | done: |
| 4860553a JH |
104 | return (sf); |
| 105 | } | |
| 106 | ||
| b4caac98 | 107 | void |
| 5c5185ae | 108 | sf_buf_ref(void *arg) |
| b4caac98 | 109 | { |
| 5c5185ae | 110 | struct sf_buf *sf = arg; |
| 382a4dbd VS |
111 | kref_inc(&sf->ref); |
| 112 | } | |
| 4860553a JH |
113 | |
| 114 | /* | |
| 5c5185ae | 115 | * Detach mapped page and release resources back to the system. |
| 4860553a | 116 | */ |
| 5c5185ae SG |
117 | int |
| 118 | sf_buf_free(void *arg) | |
| 4860553a | 119 | { |
| 5c5185ae | 120 | struct sf_buf *sf = arg; |
| 382a4dbd | 121 | int rc; |
| 5c5185ae | 122 | |
| cf327fd1 VS |
123 | rc = KREF_DEC((&sf->ref), { |
| 124 | lwbuf_free(sf->lwbuf); | |
| 125 | objcache_put(sf_buf_cache, sf); | |
| 126 | sf = NULL; | |
| 127 | }); | |
| b4caac98 | 128 | |
| 382a4dbd | 129 | return (rc); |
| 5c5185ae | 130 | } |