diff options
Diffstat (limited to 'sys/kern/uipc_syscalls.c')
-rw-r--r-- | sys/kern/uipc_syscalls.c | 68 |
1 files changed, 25 insertions, 43 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 5ba2a24..ed9d691 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -72,8 +72,7 @@ static void sf_buf_init(void *arg); SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL) static struct sf_buf *sf_buf_alloc(void); -static void sf_buf_ref(caddr_t addr, u_int size); -static void sf_buf_free(caddr_t addr, u_int size); +static void sf_buf_free(caddr_t addr, void *args); static int sendit __P((struct proc *p, int s, struct msghdr *mp, int flags)); static int recvit __P((struct proc *p, int s, struct msghdr *mp, @@ -1354,58 +1353,42 @@ sf_buf_alloc() } SLIST_REMOVE_HEAD(&sf_freelist, free_list); splx(s); - sf->refcnt = 1; return (sf); } #define dtosf(x) (&sf_bufs[((uintptr_t)(x) - (uintptr_t)sf_base) >> PAGE_SHIFT]) -static void -sf_buf_ref(caddr_t addr, u_int size) -{ - struct sf_buf *sf; - - sf = dtosf(addr); - if (sf->refcnt == 0) - panic("sf_buf_ref: referencing a free sf_buf"); - sf->refcnt++; -} /* - * Lose a reference to an sf_buf. When none left, detach mapped page - * and release resources back to the system. + * + * Detatch mapped page and release resources back to the system. * * Must be called at splimp. */ static void -sf_buf_free(caddr_t addr, u_int size) +sf_buf_free(caddr_t addr, void *args) { struct sf_buf *sf; struct vm_page *m; int s; sf = dtosf(addr); - if (sf->refcnt == 0) - panic("sf_buf_free: freeing free sf_buf"); - sf->refcnt--; - if (sf->refcnt == 0) { - pmap_qremove((vm_offset_t)addr, 1); - m = sf->m; - s = splvm(); - vm_page_unwire(m, 0); - /* - * Check for the object going away on us. This can - * happen since we don't hold a reference to it. - * If so, we're responsible for freeing the page. - */ - if (m->wire_count == 0 && m->object == NULL) - vm_page_free(m); - splx(s); - sf->m = NULL; - SLIST_INSERT_HEAD(&sf_freelist, sf, free_list); - if (sf_buf_alloc_want) { - sf_buf_alloc_want = 0; - wakeup(&sf_freelist); - } + pmap_qremove((vm_offset_t)addr, 1); + m = sf->m; + s = splvm(); + vm_page_unwire(m, 0); + /* + * Check for the object going away on us. This can + * happen since we don't hold a reference to it. + * If so, we're responsible for freeing the page. + */ + if (m->wire_count == 0 && m->object == NULL) + vm_page_free(m); + splx(s); + sf->m = NULL; + SLIST_INSERT_HEAD(&sf_freelist, sf, free_list); + if (sf_buf_alloc_want) { + sf_buf_alloc_want = 0; + wakeup(&sf_freelist); } } @@ -1630,12 +1613,11 @@ retry_lookup: error = ENOBUFS; goto done; } - m->m_ext.ext_free = sf_buf_free; - m->m_ext.ext_ref = sf_buf_ref; - m->m_ext.ext_buf = (void *)sf->kva; - m->m_ext.ext_size = PAGE_SIZE; + /* + * Setup external storage for mbuf. + */ + MEXTADD(m, sf->kva, PAGE_SIZE, sf_buf_free, NULL); m->m_data = (char *) sf->kva + pgoff; - m->m_flags |= M_EXT; m->m_pkthdr.len = m->m_len = xfsize; /* * Add the buffer to the socket buffer chain. |