summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2014-08-11 12:59:55 +0000
committerglebius <glebius@FreeBSD.org>2014-08-11 12:59:55 +0000
commit22028ff4aa5e9b83aa7c88f71456cf2f60b406e6 (patch)
treeb820d4b27b821cf0b2b136f69b5836bf54254136
parent41f23f3992a9000c140a2012fa3e493a7e75bbbd (diff)
downloadFreeBSD-src-22028ff4aa5e9b83aa7c88f71456cf2f60b406e6.zip
FreeBSD-src-22028ff4aa5e9b83aa7c88f71456cf2f60b406e6.tar.gz
Provide sf_buf_ref() to optimize refcounting of already allocated
sendfile(2) buffers. Sponsored by: Netflix Sponsored by: Nginx, Inc.
-rw-r--r--sys/kern/subr_sfbuf.c16
-rw-r--r--sys/kern/uipc_syscalls.c3
-rw-r--r--sys/sys/sf_buf.h6
3 files changed, 23 insertions, 2 deletions
diff --git a/sys/kern/subr_sfbuf.c b/sys/kern/subr_sfbuf.c
index e4309d1..1950f69 100644
--- a/sys/kern/subr_sfbuf.c
+++ b/sys/kern/subr_sfbuf.c
@@ -201,6 +201,22 @@ sf_buf_free(struct sf_buf *sf)
mtx_unlock(&sf_buf_lock);
}
+void
+sf_buf_ref(struct sf_buf *sf)
+{
+
+#ifdef SFBUF_OPTIONAL_DIRECT_MAP
+ if (SFBUF_OPTIONAL_DIRECT_MAP)
+ return;
+#endif
+
+ KASSERT(sf->ref_count > 0, ("%s: sf %p not allocated", __func__, sf));
+
+ mtx_lock(&sf_buf_lock);
+ sf->ref_count++;
+ mtx_unlock(&sf_buf_lock);
+}
+
#ifdef SFBUF_PROCESS_PAGE
/*
* Run callback function on sf_buf that holds a certain page.
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 4675f19..43dd56b 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1993,8 +1993,7 @@ sf_ext_ref(void *arg1, void *arg2)
struct sendfile_sync *sfs = arg2;
vm_page_t pg = sf_buf_page(sf);
- /* XXXGL: there should be sf_buf_ref() */
- sf_buf_alloc(sf_buf_page(sf), SFB_NOWAIT);
+ sf_buf_ref(sf);
vm_page_lock(pg);
vm_page_wire(pg);
diff --git a/sys/sys/sf_buf.h b/sys/sys/sf_buf.h
index 8a6c56f..7ab9443 100644
--- a/sys/sys/sf_buf.h
+++ b/sys/sys/sf_buf.h
@@ -106,6 +106,7 @@ struct sf_buf;
#ifdef SFBUF
struct sf_buf *sf_buf_alloc(struct vm_page *, int);
void sf_buf_free(struct sf_buf *);
+void sf_buf_ref(struct sf_buf *);
static inline vm_offset_t
sf_buf_kva(struct sf_buf *sf)
@@ -168,6 +169,11 @@ static inline void
sf_buf_free(struct sf_buf *sf)
{
}
+
+static inline void
+sf_buf_ref(struct sf_buf *sf)
+{
+}
#endif /* SFBUF */
/*
OpenPOWER on IntegriCloud