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