sf_buf.h revision 302408
11592Srgrimes/*- 21592Srgrimes * Copyright (c) 2014 Gleb Smirnoff <glebius@FreeBSD.org> 31592Srgrimes * Copyright (c) 2003-2004 Alan L. Cox <alc@cs.rice.edu> 41592Srgrimes * All rights reserved. 51592Srgrimes * 61592Srgrimes * Redistribution and use in source and binary forms, with or without 71592Srgrimes * modification, are permitted provided that the following conditions 81592Srgrimes * are met: 91592Srgrimes * 1. Redistributions of source code must retain the above copyright 101592Srgrimes * notice, this list of conditions and the following disclaimer. 111592Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 121592Srgrimes * notice, this list of conditions and the following disclaimer in the 131592Srgrimes * documentation and/or other materials provided with the distribution. 141592Srgrimes * 151592Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 161592Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 171592Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 181592Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 191592Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 201592Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 211592Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 221592Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 231592Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 241592Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 251592Srgrimes * SUCH DAMAGE. 261592Srgrimes * 271592Srgrimes * $FreeBSD: stable/11/sys/sys/sf_buf.h 293439 2016-01-08 20:34:57Z glebius $ 281592Srgrimes */ 291592Srgrimes 301592Srgrimes#ifndef _SYS_SF_BUF_H_ 311592Srgrimes#define _SYS_SF_BUF_H_ 321592Srgrimes 331592Srgrimesstruct sfstat { /* sendfile statistics */ 341592Srgrimes uint64_t sf_syscalls; /* times sendfile was called */ 351592Srgrimes uint64_t sf_noiocnt; /* times sendfile didn't require I/O */ 361592Srgrimes uint64_t sf_iocnt; /* times sendfile had to do disk I/O */ 371592Srgrimes uint64_t sf_pages_read; /* pages read as part of a request */ 381592Srgrimes uint64_t sf_pages_valid; /* pages were valid for a request */ 391592Srgrimes uint64_t sf_rhpages_requested; /* readahead pages requested */ 401592Srgrimes uint64_t sf_rhpages_read; /* readahead pages read */ 411592Srgrimes uint64_t sf_busy; /* times aborted on a busy page */ 421592Srgrimes uint64_t sf_allocfail; /* times sfbuf allocation failed */ 431592Srgrimes uint64_t sf_allocwait; /* times sfbuf allocation had to wait */ 4431329Scharnier}; 451592Srgrimes 4631329Scharnier#ifdef _KERNEL 4731329Scharnier#include <sys/types.h> 4850476Speter#include <sys/systm.h> 491592Srgrimes#include <sys/counter.h> 501592Srgrimes#include <vm/vm.h> 511592Srgrimes#include <vm/vm_param.h> 521592Srgrimes#include <vm/vm_page.h> 531592Srgrimes 541592Srgrimes/* 551592Srgrimes * Sf_bufs, or sendfile(2) buffers provide a vm_page that is mapped 561592Srgrimes * into kernel address space. Note, that they aren't used only 571592Srgrimes * by sendfile(2)! 581592Srgrimes * 591592Srgrimes * Sf_bufs could be implemented as a feature of vm_page_t, but that 601592Srgrimes * would require growth of the structure. That's why they are implemented 6192090Smaxim * as a separate hash indexed by vm_page address. Implementation lives in 6292272Smaxim * kern/subr_sfbuf.c. Meanwhile, most 64-bit machines have a physical map, 6392090Smaxim * so they don't require this hash at all, thus ignore subr_sfbuf.c. 6456668Sshin * 651592Srgrimes * Different 32-bit architectures demand different requirements on sf_buf 661592Srgrimes * hash and functions. They request features in machine/vmparam.h, which 671592Srgrimes * enable parts of this file. They can also optionally provide helpers in 681592Srgrimes * machine/sf_buf.h 691592Srgrimes * 701592Srgrimes * Defines are: 711592Srgrimes * SFBUF This machine requires sf_buf hash. 721592Srgrimes * subr_sfbuf.c should be compiled. 731592Srgrimes * SFBUF_CPUSET This machine can perform SFB_CPUPRIVATE mappings, 741592Srgrimes * that do no invalidate cache on the rest of CPUs. 75109380Syar * SFBUF_NOMD This machine doesn't have machine/sf_buf.h 761592Srgrimes * 7756668Sshin * SFBUF_OPTIONAL_DIRECT_MAP Value of this define is used as boolean 781592Srgrimes * variable that tells whether machine is 791592Srgrimes * capable of direct map or not at runtime. 801592Srgrimes * SFBUF_MAP This machine provides its own sf_buf_map() and 81110036Syar * sf_buf_unmap(). 8217435Spst * SFBUF_PROCESS_PAGE This machine provides sf_buf_process_page() 831592Srgrimes * function. 841592Srgrimes */ 851592Srgrimes 8676096Smarkm#ifdef SFBUF 871592Srgrimes#if defined(SMP) && defined(SFBUF_CPUSET) 881592Srgrimes#include <sys/_cpuset.h> 891592Srgrimes#endif 9027650Sdavidn#include <sys/queue.h> 9127650Sdavidn 921592Srgrimesstruct sf_buf { 931592Srgrimes LIST_ENTRY(sf_buf) list_entry; /* list of buffers */ 941592Srgrimes TAILQ_ENTRY(sf_buf) free_entry; /* list of buffers */ 951592Srgrimes vm_page_t m; /* currently mapped page */ 9670102Sphk vm_offset_t kva; /* va of mapping */ 9770102Sphk int ref_count; /* usage of this mapping */ 9882460Snik#if defined(SMP) && defined(SFBUF_CPUSET) 9982796Ssheldonh cpuset_t cpumask; /* where mapping is valid */ 100100684Syar#endif 1011592Srgrimes}; 1021592Srgrimes#else /* ! SFBUF */ 1031592Srgrimesstruct sf_buf; 1041592Srgrimes#endif /* SFBUF */ 1051592Srgrimes 1061592Srgrimes#ifndef SFBUF_NOMD 10789935Syar#include <machine/sf_buf.h> 1081592Srgrimes#endif 10988935Sdwmalone#ifdef SFBUF_OPTIONAL_DIRECT_MAP 1101592Srgrimes#include <machine/md_var.h> 11156668Sshin#endif 11256668Sshin 1131592Srgrimes#ifdef SFBUF 1141592Srgrimesstruct sf_buf *sf_buf_alloc(struct vm_page *, int); 1151592Srgrimesvoid sf_buf_free(struct sf_buf *); 11692272Smaximvoid sf_buf_ref(struct sf_buf *); 11792272Smaxim 11892272Smaximstatic inline vm_offset_t 11992272Smaximsf_buf_kva(struct sf_buf *sf) 1201592Srgrimes{ 1211592Srgrimes#ifdef SFBUF_OPTIONAL_DIRECT_MAP 1221592Srgrimes if (SFBUF_OPTIONAL_DIRECT_MAP) 1231592Srgrimes return (SFBUF_PHYS_DMAP(VM_PAGE_TO_PHYS((vm_page_t)sf))); 1241592Srgrimes#endif 1251592Srgrimes 12656668Sshin return (sf->kva); 1271592Srgrimes} 1281592Srgrimes 1291592Srgrimesstatic inline vm_page_t 1301592Srgrimessf_buf_page(struct sf_buf *sf) 1311592Srgrimes{ 1321592Srgrimes#ifdef SFBUF_OPTIONAL_DIRECT_MAP 1331592Srgrimes if (SFBUF_OPTIONAL_DIRECT_MAP) 1341592Srgrimes return ((vm_page_t)sf); 1351592Srgrimes#endif 1361592Srgrimes 13756668Sshin return (sf->m); 1381592Srgrimes} 13975535Sphk 1401592Srgrimes#ifndef SFBUF_MAP 141102565Syar#include <vm/pmap.h> 1421592Srgrimes 1431592Srgrimesstatic inline void 14492272Smaximsf_buf_map(struct sf_buf *sf, int flags) 1451592Srgrimes{ 14692272Smaxim 14792272Smaxim pmap_qenter(sf->kva, &sf->m, 1); 14892272Smaxim} 14975567Speter 150102565Syarstatic inline int 1511592Srgrimessf_buf_unmap(struct sf_buf *sf) 1521592Srgrimes{ 1531592Srgrimes 1541592Srgrimes return (0); 1551592Srgrimes} 1561592Srgrimes#endif /* SFBUF_MAP */ 1571592Srgrimes 1581592Srgrimes#if defined(SMP) && defined(SFBUF_CPUSET) 1591592Srgrimesvoid sf_buf_shootdown(struct sf_buf *, int); 16088935Sdwmalone#endif 16188935Sdwmalone 1621592Srgrimes#ifdef SFBUF_PROCESS_PAGE 1631592Srgrimesboolean_t sf_buf_process_page(vm_page_t, void (*)(struct sf_buf *)); 1641592Srgrimes#endif 1651592Srgrimes 1661592Srgrimes#else /* ! SFBUF */ 1671592Srgrimes 1681592Srgrimesstatic inline struct sf_buf * 1691592Srgrimessf_buf_alloc(struct vm_page *m, int pri) 1701592Srgrimes{ 1711592Srgrimes 1721592Srgrimes return ((struct sf_buf *)m); 1731592Srgrimes} 1741592Srgrimes 1751592Srgrimesstatic inline void 1761592Srgrimessf_buf_free(struct sf_buf *sf) 1771592Srgrimes{ 1781592Srgrimes} 17975556Sgreen 18075556Sgreenstatic inline void 18175556Sgreensf_buf_ref(struct sf_buf *sf) 18275556Sgreen{ 18317433Spst} 1841592Srgrimes#endif /* SFBUF */ 18556668Sshin 18656668Sshin/* 18756668Sshin * Options to sf_buf_alloc() are specified through its flags argument. This 18856668Sshin * argument's value should be the result of a bitwise or'ing of one or more 18956668Sshin * of the following values. 19056668Sshin */ 19156668Sshin#define SFB_CATCH 1 /* Check signals if the allocation 19256668Sshin sleeps. */ 19356668Sshin#define SFB_CPUPRIVATE 2 /* Create a CPU private mapping. */ 19456668Sshin#define SFB_DEFAULT 0 19556668Sshin#define SFB_NOWAIT 4 /* Return NULL if all bufs are used. */ 19656668Sshin 19756668Sshinextern counter_u64_t sfstat[sizeof(struct sfstat) / sizeof(uint64_t)]; 19856668Sshin#define SFSTAT_ADD(name, val) \ 19956668Sshin counter_u64_add(sfstat[offsetof(struct sfstat, name) / sizeof(uint64_t)],\ 20056668Sshin (val)) 20156668Sshin#define SFSTAT_INC(name) SFSTAT_ADD(name, 1) 20256668Sshin#endif /* _KERNEL */ 20356668Sshin#endif /* !_SYS_SF_BUF_H_ */ 20456668Sshin