Merge ^/head r357368 through r357388.
This commit is contained in:
commit
8be7eb94e8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang1000-import/; revision=357390
@ -73,7 +73,11 @@ typedef struct {
|
||||
#define EXIT_FAILURE 1
|
||||
#define EXIT_SUCCESS 0
|
||||
|
||||
#define RAND_MAX 0x7ffffffd
|
||||
/*
|
||||
* I.e., INT_MAX; rand(3) returns a signed integer but must produce output in
|
||||
* the range [0, RAND_MAX], so half of the possible output range is unused.
|
||||
*/
|
||||
#define RAND_MAX 0x7fffffff
|
||||
|
||||
__BEGIN_DECLS
|
||||
#ifdef _XLOCALE_H_
|
||||
|
@ -54,8 +54,6 @@ FBSD_1.0 {
|
||||
radixsort;
|
||||
sradixsort;
|
||||
rand_r;
|
||||
rand;
|
||||
srand;
|
||||
srandom;
|
||||
srandomdev;
|
||||
initstate;
|
||||
@ -125,6 +123,8 @@ FBSD_1.5 {
|
||||
|
||||
FBSD_1.6 {
|
||||
qsort_s;
|
||||
rand;
|
||||
srand;
|
||||
};
|
||||
|
||||
FBSDprivate_1.0 {
|
||||
|
@ -32,7 +32,7 @@
|
||||
.\" @(#)rand.3 8.1 (Berkeley) 6/4/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 14, 2019
|
||||
.Dd February 1, 2020
|
||||
.Dt RAND 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -59,49 +59,52 @@ Applications which require unpredictable random numbers should use
|
||||
instead.
|
||||
.Ef
|
||||
.Pp
|
||||
These interfaces are obsoleted by
|
||||
.Xr random 3 .
|
||||
.Pp
|
||||
The
|
||||
.Fn rand
|
||||
function computes a sequence of pseudo-random integers in the range
|
||||
of 0 to
|
||||
.Dv RAND_MAX
|
||||
(as defined by the header file
|
||||
.In stdlib.h ) .
|
||||
.Dv RAND_MAX ,
|
||||
inclusive.
|
||||
.Pp
|
||||
The
|
||||
.Fn srand
|
||||
function sets its argument
|
||||
function seeds the algorithm with the
|
||||
.Fa seed
|
||||
as the seed for a new sequence of
|
||||
pseudo-random numbers to be returned by
|
||||
.Fn rand .
|
||||
These sequences are repeatable by calling
|
||||
parameter.
|
||||
Repeatable sequences of
|
||||
.Fn rand
|
||||
output may be obtained by calling
|
||||
.Fn srand
|
||||
with the same seed value.
|
||||
with the same
|
||||
.Fa seed .
|
||||
.Fn rand
|
||||
is implicitly initialized as if
|
||||
.Fn srand "1"
|
||||
had been invoked explicitly.
|
||||
.Pp
|
||||
If no
|
||||
.Fa seed
|
||||
value is provided, the functions are automatically
|
||||
seeded with a value of 1.
|
||||
.Pp
|
||||
The
|
||||
In
|
||||
.Fx 13 ,
|
||||
.Fn rand
|
||||
is implemented using the same 128-byte state LFSR generator algorithm as
|
||||
.Xr random 3 .
|
||||
However, the legacy
|
||||
.Fn rand_r
|
||||
function
|
||||
provides the same functionality as
|
||||
.Fn rand .
|
||||
A pointer to the context value
|
||||
.Fa ctx
|
||||
must be supplied by the caller.
|
||||
.Pp
|
||||
For better generator quality, use
|
||||
.Xr random 3
|
||||
or
|
||||
.Xr lrand48 3 .
|
||||
function is not (and can not be, because of its limited
|
||||
.Fa *ctx
|
||||
size).
|
||||
.Fn rand_r
|
||||
implements the historical, poor-quality Park-Miller 32-bit LCG and should not
|
||||
be used in new designs.
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
Since
|
||||
.Fx 13 ,
|
||||
.Fn rand
|
||||
is implemented with the same generator as
|
||||
.Xr random 3 ,
|
||||
so the low-order bits should no longer be significantly worse than the
|
||||
high-order bits.
|
||||
.Sh SEE ALSO
|
||||
.Xr arc4random 3 ,
|
||||
.Xr lrand48 3 ,
|
||||
.Xr random 3 ,
|
||||
.Xr random 4
|
||||
.Sh STANDARDS
|
||||
@ -115,5 +118,32 @@ conform to
|
||||
.Pp
|
||||
The
|
||||
.Fn rand_r
|
||||
function is marked as obsolescent in POSIX and may be removed in a future
|
||||
revision of the standard.
|
||||
function is not part of
|
||||
.St -isoC
|
||||
and is marked obsolescent in
|
||||
.St -p1003.1-2008 .
|
||||
It may be removed in a future revision of POSIX.
|
||||
.Sh CAVEATS
|
||||
Prior to
|
||||
.Fx 13 ,
|
||||
.Fn rand
|
||||
used the historical Park-Miller generator with 32 bits of state and produced
|
||||
poor quality output, especially in the lower bits.
|
||||
.Fn rand
|
||||
in earlier versions of
|
||||
.Fx ,
|
||||
as well as other standards-conforming implementations, may continue to produce
|
||||
poor quality output.
|
||||
.Pp
|
||||
.Em These functions should not be used in portable applications that want a
|
||||
.Em high quality or high performance pseudorandom number generator .
|
||||
One possible replacement,
|
||||
.Xr random 3 ,
|
||||
is portable to Linux — but it is not especially fast, nor standardized.
|
||||
.Pp
|
||||
If broader portability or better performance is desired, any of the widely
|
||||
available and permissively licensed SFC64/32, JSF64/32, PCG64/32, or SplitMix64
|
||||
algorithm implementations may be embedded in your application.
|
||||
These algorithms have the benefit of requiring less space than
|
||||
.Xr random 3
|
||||
and being quite fast (in header inline implementations).
|
||||
|
@ -40,11 +40,60 @@ __FBSDID("$FreeBSD$");
|
||||
#include "namespace.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "random.h"
|
||||
|
||||
/*
|
||||
* Implement rand(3), the standard C PRNG API, using the non-standard but
|
||||
* higher quality random(3) implementation and the same size 128-byte state
|
||||
* LFSR as the random(3) default.
|
||||
*
|
||||
* It turns out there are portable applications that want a PRNG but are too
|
||||
* lazy to use better-but-nonstandard interfaces like random(3), when
|
||||
* available, and too lazy to import higher-quality and faster PRNGs into their
|
||||
* codebase (such as any of SFC, JSF, 128-bit LCGs, PCG, or Splitmix64).
|
||||
*
|
||||
* Since we're stuck with rand(3) due to the C standard, we can at least have
|
||||
* it produce a relatively good PRNG sequence using our existing random(3)
|
||||
* LFSR. The random(3) design is not particularly fast nor compact, but it has
|
||||
* the advantage of being the one already in the tree.
|
||||
*/
|
||||
static struct __random_state *rand3_state;
|
||||
|
||||
static void
|
||||
initialize_rand3(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
rand3_state = allocatestate(TYPE_3);
|
||||
error = initstate_r(rand3_state, 1, rand3_state->rst_randtbl, BREAK_3);
|
||||
assert(error == 0);
|
||||
}
|
||||
|
||||
int
|
||||
rand(void)
|
||||
{
|
||||
if (rand3_state == NULL)
|
||||
initialize_rand3();
|
||||
return ((int)random_r(rand3_state));
|
||||
}
|
||||
|
||||
void
|
||||
srand(unsigned seed)
|
||||
{
|
||||
if (rand3_state == NULL)
|
||||
initialize_rand3();
|
||||
srandom_r(rand3_state, seed);
|
||||
}
|
||||
|
||||
/*
|
||||
* FreeBSD 12 and prior compatibility implementation of rand(3).
|
||||
*/
|
||||
static int
|
||||
do_rand(unsigned long *ctx)
|
||||
{
|
||||
@ -71,7 +120,9 @@ do_rand(unsigned long *ctx)
|
||||
return (x);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Can't fix this garbage; too little state.
|
||||
*/
|
||||
int
|
||||
rand_r(unsigned *ctx)
|
||||
{
|
||||
@ -84,21 +135,23 @@ rand_r(unsigned *ctx)
|
||||
return (r);
|
||||
}
|
||||
|
||||
|
||||
static u_long next = 1;
|
||||
|
||||
int __rand_fbsd12(void);
|
||||
int
|
||||
rand(void)
|
||||
__rand_fbsd12(void)
|
||||
{
|
||||
return (do_rand(&next));
|
||||
}
|
||||
__sym_compat(rand, __rand_fbsd12, FBSD_1.0);
|
||||
|
||||
void __srand_fbsd12(unsigned seed);
|
||||
void
|
||||
srand(unsigned seed)
|
||||
__srand_fbsd12(unsigned seed)
|
||||
{
|
||||
next = seed;
|
||||
}
|
||||
|
||||
__sym_compat(srand, __srand_fbsd12, FBSD_1.0);
|
||||
|
||||
void __sranddev_fbsd12(void);
|
||||
void
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)random.3 8.1 (Berkeley) 6/4/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 20, 2020
|
||||
.Dd February 1, 2020
|
||||
.Dt RANDOM 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -74,8 +74,7 @@ The period of this random number generator is very large, approximately
|
||||
.Pp
|
||||
If initialized with less than 32 bytes of state,
|
||||
.Fn random
|
||||
uses the same poor-quality Park-Miller LCG as
|
||||
.Xr rand 3 .
|
||||
uses the poor-quality 32-bit Park-Miller LCG.
|
||||
.Pp
|
||||
The
|
||||
.Fn random
|
||||
@ -85,9 +84,6 @@ functions are analagous to
|
||||
.Xr rand 3
|
||||
and
|
||||
.Xr srand 3 .
|
||||
The difference is that
|
||||
.Xr rand 3
|
||||
is a worse pseudo-random number generator.
|
||||
.Pp
|
||||
Like
|
||||
.Xr rand 3 ,
|
||||
|
@ -104,48 +104,13 @@ __FBSDID("$FreeBSD$");
|
||||
* byte buffer it is about 5 percent faster.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For each of the currently supported random number generators, we have a
|
||||
* break value on the amount of state information (you need at least this
|
||||
* many bytes of state info to support this random number generator), a degree
|
||||
* for the polynomial (actually a trinomial) that the R.N.G. is based on, and
|
||||
* the separation between the two lower order coefficients of the trinomial.
|
||||
*/
|
||||
#define TYPE_0 0 /* linear congruential */
|
||||
#define BREAK_0 8
|
||||
#define DEG_0 0
|
||||
#define SEP_0 0
|
||||
|
||||
#define TYPE_1 1 /* x**7 + x**3 + 1 */
|
||||
#define BREAK_1 32
|
||||
#define DEG_1 7
|
||||
#define SEP_1 3
|
||||
|
||||
#define TYPE_2 2 /* x**15 + x + 1 */
|
||||
#define BREAK_2 64
|
||||
#define DEG_2 15
|
||||
#define SEP_2 1
|
||||
|
||||
#define TYPE_3 3 /* x**31 + x**3 + 1 */
|
||||
#define BREAK_3 128
|
||||
#define DEG_3 31
|
||||
#define SEP_3 3
|
||||
|
||||
#define TYPE_4 4 /* x**63 + x + 1 */
|
||||
#define BREAK_4 256
|
||||
#define DEG_4 63
|
||||
#define SEP_4 1
|
||||
|
||||
/*
|
||||
* Array versions of the above information to make code run faster --
|
||||
* relies on fact that TYPE_i == i.
|
||||
*/
|
||||
#define MAX_TYPES 5 /* max number of types above */
|
||||
|
||||
#define NSHUFF 50 /* to drop some "seed -> 1st value" linearity */
|
||||
|
||||
static const int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
|
||||
static const int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
|
||||
static const int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
|
||||
static const int breaks[MAX_TYPES] = {
|
||||
BREAK_0, BREAK_1, BREAK_2, BREAK_3, BREAK_4
|
||||
};
|
||||
|
||||
/*
|
||||
* Initially, everything is set up as if from:
|
||||
@ -524,3 +489,19 @@ random(void)
|
||||
{
|
||||
return (random_r(&implicit));
|
||||
}
|
||||
|
||||
struct __random_state *
|
||||
allocatestate(unsigned type)
|
||||
{
|
||||
size_t asize;
|
||||
|
||||
/* No point using this interface to get the Park-Miller LCG. */
|
||||
if (type < TYPE_1)
|
||||
abort();
|
||||
/* Clamp to widest supported variant. */
|
||||
if (type > (MAX_TYPES - 1))
|
||||
type = (MAX_TYPES - 1);
|
||||
|
||||
asize = sizeof(struct __random_state) + (size_t)breaks[type];
|
||||
return (malloc(asize));
|
||||
}
|
||||
|
@ -27,6 +27,44 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* For each of the currently supported random number generators, we have a
|
||||
* break value on the amount of state information (you need at least this
|
||||
* many bytes of state info to support this random number generator), a degree
|
||||
* for the polynomial (actually a trinomial) that the R.N.G. is based on, and
|
||||
* the separation between the two lower order coefficients of the trinomial.
|
||||
*/
|
||||
#define TYPE_0 0 /* linear congruential */
|
||||
#define BREAK_0 8
|
||||
#define DEG_0 0
|
||||
#define SEP_0 0
|
||||
|
||||
#define TYPE_1 1 /* x**7 + x**3 + 1 */
|
||||
#define BREAK_1 32
|
||||
#define DEG_1 7
|
||||
#define SEP_1 3
|
||||
|
||||
#define TYPE_2 2 /* x**15 + x + 1 */
|
||||
#define BREAK_2 64
|
||||
#define DEG_2 15
|
||||
#define SEP_2 1
|
||||
|
||||
#define TYPE_3 3 /* x**31 + x**3 + 1 */
|
||||
#define BREAK_3 128
|
||||
#define DEG_3 31
|
||||
#define SEP_3 3
|
||||
|
||||
#define TYPE_4 4 /* x**63 + x + 1 */
|
||||
#define BREAK_4 256
|
||||
#define DEG_4 63
|
||||
#define SEP_4 1
|
||||
|
||||
/*
|
||||
* Array versions of the above information to make code run faster --
|
||||
* relies on fact that TYPE_i == i.
|
||||
*/
|
||||
#define MAX_TYPES 5 /* max number of types above */
|
||||
|
||||
/* A full instance of the random(3) generator. */
|
||||
struct __random_state {
|
||||
uint32_t *rst_fptr;
|
||||
@ -40,6 +78,7 @@ struct __random_state {
|
||||
uint32_t rst_randtbl[];
|
||||
};
|
||||
|
||||
struct __random_state *allocatestate(unsigned type);
|
||||
int initstate_r(struct __random_state *, unsigned, uint32_t *, size_t);
|
||||
long random_r(struct __random_state *);
|
||||
void srandom_r(struct __random_state *, unsigned);
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 22, 2020
|
||||
.Dd February 1, 2020
|
||||
.Dt HWPSTATE_INTEL 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -49,7 +49,15 @@ Can be used to disable
|
||||
.Nm ,
|
||||
allowing other compatible drivers to manage performance states, like
|
||||
.Xr est 4 .
|
||||
.Pq default 0
|
||||
Defaults to
|
||||
.Dv Qq 0
|
||||
(enabled).
|
||||
.It Va machdep.hwpstate_pkg_ctrl
|
||||
Selects between package-level control (the default) and per-core control.
|
||||
.Dv Qq 1
|
||||
selects package-level control and
|
||||
.Dv Qq 0
|
||||
selects core-level control.
|
||||
.El
|
||||
.Sh SYSCTL VARIABLES
|
||||
The following
|
||||
|
@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
@ -60,28 +60,25 @@ __FBSDID("$FreeBSD$");
|
||||
* Find pathname of process's current directory.
|
||||
*/
|
||||
int
|
||||
linux_getcwd(struct thread *td, struct linux_getcwd_args *args)
|
||||
linux_getcwd(struct thread *td, struct linux_getcwd_args *uap)
|
||||
{
|
||||
char *path;
|
||||
int error, lenused;
|
||||
char *buf, *retbuf;
|
||||
size_t buflen;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Linux returns ERANGE instead of EINVAL.
|
||||
*/
|
||||
if (args->bufsize < 2)
|
||||
buflen = uap->bufsize;
|
||||
if (__predict_false(buflen < 2))
|
||||
return (ERANGE);
|
||||
if (buflen > LINUX_PATH_MAX)
|
||||
buflen = LINUX_PATH_MAX;
|
||||
|
||||
path = malloc(LINUX_PATH_MAX, M_LINUX, M_WAITOK);
|
||||
|
||||
error = kern___getcwd(td, path, UIO_SYSSPACE, args->bufsize,
|
||||
LINUX_PATH_MAX);
|
||||
buf = malloc(buflen, M_TEMP, M_WAITOK);
|
||||
error = vn_getcwd(td, buf, &retbuf, &buflen);
|
||||
if (error == 0) {
|
||||
lenused = strlen(path) + 1;
|
||||
error = copyout(path, args->buf, lenused);
|
||||
error = copyout(retbuf, uap->buf, buflen);
|
||||
if (error == 0)
|
||||
td->td_retval[0] = lenused;
|
||||
td->td_retval[0] = buflen;
|
||||
}
|
||||
|
||||
free(path, M_LINUX);
|
||||
free(buf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
@ -70,7 +70,8 @@ __FBSDID("$FreeBSD$");
|
||||
#define TPM_CRB_CTRL_STS_ERR_BIT BIT(0)
|
||||
#define TPM_CRB_CTRL_STS_IDLE_BIT BIT(1)
|
||||
|
||||
#define TPM_CRB_CTRL_CANCEL_CMD BIT(0)
|
||||
#define TPM_CRB_CTRL_CANCEL_CMD 0x1
|
||||
#define TPM_CRB_CTRL_CANCEL_CLEAR 0x0
|
||||
|
||||
#define TPM_CRB_CTRL_START_CMD BIT(0)
|
||||
|
||||
@ -298,7 +299,7 @@ tpmcrb_cancel_cmd(struct tpm_sc *sc)
|
||||
return (false);
|
||||
}
|
||||
|
||||
WR4(sc, TPM_CRB_CTRL_CANCEL, ~TPM_CRB_CTRL_CANCEL_CMD);
|
||||
WR4(sc, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR;
|
||||
return (true);
|
||||
}
|
||||
|
||||
@ -330,7 +331,7 @@ tpmcrb_transmit(struct tpm_sc *sc, size_t length)
|
||||
return (EIO);
|
||||
}
|
||||
/* Clear cancellation bit */
|
||||
WR4(sc, TPM_CRB_CTRL_CANCEL, ~TPM_CRB_CTRL_CANCEL_CMD);
|
||||
WR4(sc, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR;
|
||||
|
||||
/* Switch device to idle state if necessary */
|
||||
if (!(RD4(sc, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_IDLE_BIT)) {
|
||||
|
@ -386,12 +386,11 @@ tpmtis_go_ready(struct tpm_sc *sc)
|
||||
mask = TPM_STS_CMD_RDY;
|
||||
sc->intr_type = TPM_INT_STS_CMD_RDY;
|
||||
|
||||
OR4(sc, TPM_STS, TPM_STS_CMD_RDY);
|
||||
WR4(sc, TPM_STS, TPM_STS_CMD_RDY);
|
||||
bus_barrier(sc->mem_res, TPM_STS, 4, BUS_SPACE_BARRIER_WRITE);
|
||||
if (!tpm_wait_for_u32(sc, TPM_STS, mask, mask, TPM_TIMEOUT_B))
|
||||
return (false);
|
||||
|
||||
AND4(sc, TPM_STS, ~TPM_STS_CMD_RDY);
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
@ -274,7 +274,7 @@ devfs_vptocnp(struct vop_vptocnp_args *ap)
|
||||
struct vnode **dvp = ap->a_vpp;
|
||||
struct devfs_mount *dmp;
|
||||
char *buf = ap->a_buf;
|
||||
int *buflen = ap->a_buflen;
|
||||
size_t *buflen = ap->a_buflen;
|
||||
struct devfs_dirent *dd, *de;
|
||||
int i, error;
|
||||
|
||||
|
@ -377,7 +377,7 @@ pfs_vptocnp(struct vop_vptocnp_args *ap)
|
||||
struct pfs_node *pn;
|
||||
struct mount *mp;
|
||||
char *buf = ap->a_buf;
|
||||
int *buflen = ap->a_buflen;
|
||||
size_t *buflen = ap->a_buflen;
|
||||
char pidbuf[PFS_NAMELEN];
|
||||
pid_t pid = pvd->pvd_pid;
|
||||
int len, i, error, locked;
|
||||
|
@ -1491,7 +1491,7 @@ tmpfs_vptocnp_dir(struct tmpfs_node *tn, struct tmpfs_node *tnp,
|
||||
|
||||
static int
|
||||
tmpfs_vptocnp_fill(struct vnode *vp, struct tmpfs_node *tn,
|
||||
struct tmpfs_node *tnp, char *buf, int *buflen, struct vnode **dvp)
|
||||
struct tmpfs_node *tnp, char *buf, size_t *buflen, struct vnode **dvp)
|
||||
{
|
||||
struct tmpfs_dirent *de;
|
||||
int error, i;
|
||||
@ -1531,7 +1531,7 @@ tmpfs_vptocnp(struct vop_vptocnp_args *ap)
|
||||
struct tmpfs_dirent *de;
|
||||
struct tmpfs_mount *tm;
|
||||
char *buf;
|
||||
int *buflen;
|
||||
size_t *buflen;
|
||||
int error;
|
||||
|
||||
vp = ap->a_vp;
|
||||
|
@ -3608,6 +3608,7 @@ coredump(struct thread *td)
|
||||
struct vnode *vp;
|
||||
struct flock lf;
|
||||
struct vattr vattr;
|
||||
size_t fullpathsize;
|
||||
int error, error1, locked;
|
||||
char *name; /* name of corefile */
|
||||
void *rl_cookie;
|
||||
@ -3711,13 +3712,14 @@ coredump(struct thread *td)
|
||||
* if the path of the core is relative, add the current dir in front if it.
|
||||
*/
|
||||
if (name[0] != '/') {
|
||||
fullpath = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
|
||||
if (kern___getcwd(td, fullpath, UIO_SYSSPACE, MAXPATHLEN, MAXPATHLEN) != 0) {
|
||||
free(fullpath, M_TEMP);
|
||||
fullpathsize = MAXPATHLEN;
|
||||
freepath = malloc(fullpathsize, M_TEMP, M_WAITOK);
|
||||
if (vn_getcwd(td, freepath, &fullpath, &fullpathsize) != 0) {
|
||||
free(freepath, M_TEMP);
|
||||
goto out2;
|
||||
}
|
||||
devctl_safe_quote_sb(sb, fullpath);
|
||||
free(fullpath, M_TEMP);
|
||||
free(freepath, M_TEMP);
|
||||
sbuf_putc(sb, '/');
|
||||
}
|
||||
devctl_safe_quote_sb(sb, name);
|
||||
|
@ -364,7 +364,7 @@ STATNODE_COUNTER(numposhits, "Number of cache hits (positive)");
|
||||
STATNODE_COUNTER(numnegzaps,
|
||||
"Number of cache hits (negative) we do not want to cache");
|
||||
STATNODE_COUNTER(numneghits, "Number of cache hits (negative)");
|
||||
/* These count for kern___getcwd(), too. */
|
||||
/* These count for vn_getcwd(), too. */
|
||||
STATNODE_COUNTER(numfullpathcalls, "Number of fullpath search calls");
|
||||
STATNODE_COUNTER(numfullpathfail1, "Number of fullpath search errors (ENOTDIR)");
|
||||
STATNODE_COUNTER(numfullpathfail2,
|
||||
@ -388,7 +388,7 @@ STATNODE_COUNTER(shrinking_skipped,
|
||||
|
||||
static void cache_zap_locked(struct namecache *ncp, bool neg_locked);
|
||||
static int vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
|
||||
char *buf, char **retbuf, u_int buflen);
|
||||
char *buf, char **retbuf, size_t *buflen);
|
||||
|
||||
static MALLOC_DEFINE(M_VFSCACHE, "vfscache", "VFS name cache entries");
|
||||
|
||||
@ -2167,39 +2167,35 @@ vfs_cache_lookup(struct vop_lookup_args *ap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX All of these sysctls would probably be more productive dead.
|
||||
*/
|
||||
static int __read_mostly disablecwd;
|
||||
SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0,
|
||||
"Disable the getcwd syscall");
|
||||
|
||||
/* Implementation of the getcwd syscall. */
|
||||
int
|
||||
sys___getcwd(struct thread *td, struct __getcwd_args *uap)
|
||||
{
|
||||
char *buf, *retbuf;
|
||||
size_t buflen;
|
||||
int error;
|
||||
|
||||
return (kern___getcwd(td, uap->buf, UIO_USERSPACE, uap->buflen,
|
||||
MAXPATHLEN));
|
||||
buflen = uap->buflen;
|
||||
if (__predict_false(buflen < 2))
|
||||
return (EINVAL);
|
||||
if (buflen > MAXPATHLEN)
|
||||
buflen = MAXPATHLEN;
|
||||
|
||||
buf = malloc(buflen, M_TEMP, M_WAITOK);
|
||||
error = vn_getcwd(td, buf, &retbuf, &buflen);
|
||||
if (error == 0)
|
||||
error = copyout(retbuf, uap->buf, buflen);
|
||||
free(buf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, size_t buflen,
|
||||
size_t path_max)
|
||||
vn_getcwd(struct thread *td, char *buf, char **retbuf, size_t *buflen)
|
||||
{
|
||||
char *bp, *tmpbuf;
|
||||
struct filedesc *fdp;
|
||||
struct vnode *cdir, *rdir;
|
||||
int error;
|
||||
|
||||
if (__predict_false(disablecwd))
|
||||
return (ENODEV);
|
||||
if (__predict_false(buflen < 2))
|
||||
return (EINVAL);
|
||||
if (buflen > path_max)
|
||||
buflen = path_max;
|
||||
|
||||
tmpbuf = malloc(buflen, M_TEMP, M_WAITOK);
|
||||
fdp = td->td_proc->p_fd;
|
||||
FILEDESC_SLOCK(fdp);
|
||||
cdir = fdp->fd_cdir;
|
||||
@ -2207,32 +2203,17 @@ kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, size_t buflen,
|
||||
rdir = fdp->fd_rdir;
|
||||
vrefact(rdir);
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
error = vn_fullpath1(td, cdir, rdir, tmpbuf, &bp, buflen);
|
||||
error = vn_fullpath1(td, cdir, rdir, buf, retbuf, buflen);
|
||||
vrele(rdir);
|
||||
vrele(cdir);
|
||||
|
||||
if (!error) {
|
||||
if (bufseg == UIO_SYSSPACE)
|
||||
bcopy(bp, buf, strlen(bp) + 1);
|
||||
else
|
||||
error = copyout(bp, buf, strlen(bp) + 1);
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(curthread, KTR_NAMEI))
|
||||
ktrnamei(bp);
|
||||
if (KTRPOINT(curthread, KTR_NAMEI) && error == 0)
|
||||
ktrnamei(*retbuf);
|
||||
#endif
|
||||
}
|
||||
free(tmpbuf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Thus begins the fullpath magic.
|
||||
*/
|
||||
|
||||
static int __read_mostly disablefullpath;
|
||||
SYSCTL_INT(_debug, OID_AUTO, disablefullpath, CTLFLAG_RW, &disablefullpath, 0,
|
||||
"Disable the vn_fullpath function");
|
||||
|
||||
/*
|
||||
* Retrieve the full filesystem path that correspond to a vnode from the name
|
||||
* cache (if available)
|
||||
@ -2243,20 +2224,20 @@ vn_fullpath(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf)
|
||||
char *buf;
|
||||
struct filedesc *fdp;
|
||||
struct vnode *rdir;
|
||||
size_t buflen;
|
||||
int error;
|
||||
|
||||
if (__predict_false(disablefullpath))
|
||||
return (ENODEV);
|
||||
if (__predict_false(vn == NULL))
|
||||
return (EINVAL);
|
||||
|
||||
buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
|
||||
buflen = MAXPATHLEN;
|
||||
buf = malloc(buflen, M_TEMP, M_WAITOK);
|
||||
fdp = td->td_proc->p_fd;
|
||||
FILEDESC_SLOCK(fdp);
|
||||
rdir = fdp->fd_rdir;
|
||||
vrefact(rdir);
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
error = vn_fullpath1(td, vn, rdir, buf, retbuf, MAXPATHLEN);
|
||||
error = vn_fullpath1(td, vn, rdir, buf, retbuf, &buflen);
|
||||
vrele(rdir);
|
||||
|
||||
if (!error)
|
||||
@ -2277,14 +2258,14 @@ vn_fullpath_global(struct thread *td, struct vnode *vn,
|
||||
char **retbuf, char **freebuf)
|
||||
{
|
||||
char *buf;
|
||||
size_t buflen;
|
||||
int error;
|
||||
|
||||
if (__predict_false(disablefullpath))
|
||||
return (ENODEV);
|
||||
if (__predict_false(vn == NULL))
|
||||
return (EINVAL);
|
||||
buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
|
||||
error = vn_fullpath1(td, vn, rootvnode, buf, retbuf, MAXPATHLEN);
|
||||
buflen = MAXPATHLEN;
|
||||
buf = malloc(buflen, M_TEMP, M_WAITOK);
|
||||
error = vn_fullpath1(td, vn, rootvnode, buf, retbuf, &buflen);
|
||||
if (!error)
|
||||
*freebuf = buf;
|
||||
else
|
||||
@ -2293,7 +2274,7 @@ vn_fullpath_global(struct thread *td, struct vnode *vn,
|
||||
}
|
||||
|
||||
int
|
||||
vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf, u_int *buflen)
|
||||
vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf, size_t *buflen)
|
||||
{
|
||||
struct vnode *dvp;
|
||||
struct namecache *ncp;
|
||||
@ -2355,17 +2336,20 @@ vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf, u_int *buflen)
|
||||
}
|
||||
|
||||
/*
|
||||
* The magic behind kern___getcwd() and vn_fullpath().
|
||||
* The magic behind vn_getcwd() and vn_fullpath().
|
||||
*/
|
||||
static int
|
||||
vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
|
||||
char *buf, char **retbuf, u_int buflen)
|
||||
char *buf, char **retbuf, size_t *len)
|
||||
{
|
||||
int error, slash_prefixed;
|
||||
#ifdef KDTRACE_HOOKS
|
||||
struct vnode *startvp = vp;
|
||||
#endif
|
||||
struct vnode *vp1;
|
||||
size_t buflen;
|
||||
|
||||
buflen = *len;
|
||||
|
||||
buflen--;
|
||||
buf[buflen] = '\0';
|
||||
@ -2457,6 +2441,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
|
||||
|
||||
SDT_PROBE3(vfs, namecache, fullpath, return, 0, startvp, buf + buflen);
|
||||
*retbuf = buf + buflen;
|
||||
*len -= buflen;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -2515,9 +2500,6 @@ vn_commname(struct vnode *vp, char *buf, u_int buflen)
|
||||
* Requires a locked, referenced vnode.
|
||||
* Vnode is re-locked on success or ENODEV, otherwise unlocked.
|
||||
*
|
||||
* If sysctl debug.disablefullpath is set, ENODEV is returned,
|
||||
* vnode is left locked and path remain untouched.
|
||||
*
|
||||
* If vp is a directory, the call to vn_fullpath_global() always succeeds
|
||||
* because it falls back to the ".." lookup if the namecache lookup fails.
|
||||
*/
|
||||
@ -2532,10 +2514,6 @@ vn_path_to_global_path(struct thread *td, struct vnode *vp, char *path,
|
||||
|
||||
ASSERT_VOP_ELOCKED(vp, __func__);
|
||||
|
||||
/* Return ENODEV if sysctl debug.disablefullpath==1 */
|
||||
if (__predict_false(disablefullpath))
|
||||
return (ENODEV);
|
||||
|
||||
/* Construct global filesystem path from vp. */
|
||||
VOP_UNLOCK(vp);
|
||||
error = vn_fullpath_global(td, vp, &rpath, &fbuf);
|
||||
|
@ -804,7 +804,7 @@ vop_stdvptocnp(struct vop_vptocnp_args *ap)
|
||||
struct vnode **dvp = ap->a_vpp;
|
||||
struct ucred *cred = ap->a_cred;
|
||||
char *buf = ap->a_buf;
|
||||
int *buflen = ap->a_buflen;
|
||||
size_t *buflen = ap->a_buflen;
|
||||
char *dirbuf, *cpos;
|
||||
int i, error, eofflag, dirbuflen, flags, locked, len, covered;
|
||||
off_t off;
|
||||
|
@ -640,7 +640,7 @@ vop_vptocnp {
|
||||
OUT struct vnode **vpp;
|
||||
IN struct ucred *cred;
|
||||
INOUT char *buf;
|
||||
INOUT int *buflen;
|
||||
INOUT size_t *buflen;
|
||||
};
|
||||
|
||||
|
||||
|
@ -45,11 +45,21 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <dev/extres/clk/clk.h>
|
||||
#include <dev/extres/clk/clk_fixed.h>
|
||||
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
#include <gnu/dts/include/dt-bindings/clock/sifive-fu540-prci.h>
|
||||
|
||||
static struct ofw_compat_data compat_data[] = {
|
||||
{ "sifive,aloeprci0", 1 },
|
||||
{ "sifive,ux00prci0", 1 },
|
||||
{ "sifive,fu540-c000-prci", 1 },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
static struct resource_spec prci_spec[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
RESOURCE_SPEC_END
|
||||
@ -68,6 +78,7 @@ struct prci_softc {
|
||||
|
||||
struct prci_clk_pll_sc {
|
||||
struct prci_softc *parent_sc;
|
||||
uint32_t reg;
|
||||
};
|
||||
|
||||
#define PRCI_LOCK(sc) mtx_lock(&(sc)->mtx)
|
||||
@ -75,17 +86,51 @@ struct prci_clk_pll_sc {
|
||||
#define PRCI_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED);
|
||||
#define PRCI_ASSERT_UNLOCKED(sc) mtx_assert(&(sc)->mtx, MA_NOTOWNED);
|
||||
|
||||
#define PRCI_COREPLL 0x4
|
||||
#define PRCI_COREPLL_DIVR_MASK 0x3f
|
||||
#define PRCI_COREPLL_DIVR_SHIFT 0
|
||||
#define PRCI_COREPLL_DIVF_MASK 0x7fc0
|
||||
#define PRCI_COREPLL_DIVF_SHIFT 6
|
||||
#define PRCI_COREPLL_DIVQ_MASK 0x38000
|
||||
#define PRCI_COREPLL_DIVQ_SHIFT 15
|
||||
#define PRCI_COREPLL_CFG0 0x4
|
||||
#define PRCI_DDRPLL_CFG0 0xC
|
||||
#define PRCI_GEMGXLPLL_CFG0 0x1C
|
||||
|
||||
#define PRCI_PLL_DIVR_MASK 0x3f
|
||||
#define PRCI_PLL_DIVR_SHIFT 0
|
||||
#define PRCI_PLL_DIVF_MASK 0x7fc0
|
||||
#define PRCI_PLL_DIVF_SHIFT 6
|
||||
#define PRCI_PLL_DIVQ_MASK 0x38000
|
||||
#define PRCI_PLL_DIVQ_SHIFT 15
|
||||
|
||||
#define PRCI_READ(_sc, _reg) \
|
||||
bus_space_read_4((_sc)->bst, (_sc)->bsh, (_reg))
|
||||
|
||||
struct prci_pll_def {
|
||||
uint32_t id;
|
||||
const char *name;
|
||||
uint32_t reg;
|
||||
};
|
||||
|
||||
#define PLL(_id, _name, _base) \
|
||||
{ \
|
||||
.id = (_id), \
|
||||
.name = (_name), \
|
||||
.reg = (_base), \
|
||||
}
|
||||
|
||||
/* PLL Clocks */
|
||||
struct prci_pll_def pll_clks[] = {
|
||||
PLL(PRCI_CLK_COREPLL, "coreclk", PRCI_COREPLL_CFG0),
|
||||
PLL(PRCI_CLK_DDRPLL, "ddrclk", PRCI_DDRPLL_CFG0),
|
||||
PLL(PRCI_CLK_GEMGXLPLL, "gemgxclk", PRCI_GEMGXLPLL_CFG0),
|
||||
};
|
||||
|
||||
/* Fixed divisor clock TLCLK. */
|
||||
struct clk_fixed_def tlclk_def = {
|
||||
.clkdef.id = PRCI_CLK_TLCLK,
|
||||
.clkdef.name = "prci_tlclk",
|
||||
.clkdef.parent_names = (const char *[]){"coreclk"},
|
||||
.clkdef.parent_cnt = 1,
|
||||
.clkdef.flags = CLK_NODE_STATIC_STRINGS,
|
||||
.mult = 1,
|
||||
.div = 2,
|
||||
};
|
||||
|
||||
static int
|
||||
prci_clk_pll_init(struct clknode *clk, device_t dev)
|
||||
{
|
||||
@ -121,11 +166,11 @@ prci_clk_pll_recalc(struct clknode *clk, uint64_t *freq)
|
||||
}
|
||||
|
||||
/* Calculate the PLL output */
|
||||
val = PRCI_READ(sc->parent_sc, PRCI_COREPLL);
|
||||
val = PRCI_READ(sc->parent_sc, sc->reg);
|
||||
|
||||
divf = (val & PRCI_COREPLL_DIVF_MASK) >> PRCI_COREPLL_DIVF_SHIFT;
|
||||
divq = (val & PRCI_COREPLL_DIVQ_MASK) >> PRCI_COREPLL_DIVQ_SHIFT;
|
||||
divr = (val & PRCI_COREPLL_DIVR_MASK) >> PRCI_COREPLL_DIVR_SHIFT;
|
||||
divf = (val & PRCI_PLL_DIVF_MASK) >> PRCI_PLL_DIVF_SHIFT;
|
||||
divq = (val & PRCI_PLL_DIVQ_MASK) >> PRCI_PLL_DIVQ_SHIFT;
|
||||
divr = (val & PRCI_PLL_DIVR_MASK) >> PRCI_PLL_DIVR_SHIFT;
|
||||
|
||||
*freq = refclk / (divr + 1) * (2 * (divf + 1)) / (1 << divq);
|
||||
|
||||
@ -151,7 +196,7 @@ prci_probe(device_t dev)
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_is_compatible(dev, "sifive,aloeprci0"))
|
||||
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "SiFive FU540 Power Reset Clocking Interrupt");
|
||||
@ -160,7 +205,8 @@ prci_probe(device_t dev)
|
||||
}
|
||||
|
||||
static void
|
||||
prci_pll_register(struct prci_softc *parent_sc, struct clknode_init_def *clkdef)
|
||||
prci_pll_register(struct prci_softc *parent_sc, struct clknode_init_def *clkdef,
|
||||
uint32_t reg)
|
||||
{
|
||||
struct clknode *clk;
|
||||
struct prci_clk_pll_sc *sc;
|
||||
@ -172,6 +218,7 @@ prci_pll_register(struct prci_softc *parent_sc, struct clknode_init_def *clkdef)
|
||||
|
||||
sc = clknode_get_softc(clk);
|
||||
sc->parent_sc = parent_sc;
|
||||
sc->reg = reg;
|
||||
|
||||
clknode_register(parent_sc->clkdom, clk);
|
||||
}
|
||||
@ -201,14 +248,12 @@ prci_attach(device_t dev)
|
||||
node = ofw_bus_get_node(dev);
|
||||
error = ofw_bus_parse_xref_list_get_length(node, "clocks",
|
||||
"#clock-cells", &ncells);
|
||||
if (error != 0 || ncells != 1) {
|
||||
if (error != 0 || ncells < 1) {
|
||||
device_printf(dev, "couldn't find parent clock\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bzero(&clkdef, sizeof(clkdef));
|
||||
clkdef.id = 0;
|
||||
clkdef.name = "coreclk";
|
||||
clkdef.parent_names = mallocarray(ncells, sizeof(char *), M_OFWPROP,
|
||||
M_WAITOK);
|
||||
for (i = 0; i < ncells; i++) {
|
||||
@ -232,7 +277,21 @@ prci_attach(device_t dev)
|
||||
}
|
||||
|
||||
/* We can't free a clkdom, so from now on we cannot fail. */
|
||||
prci_pll_register(sc, &clkdef);
|
||||
for (i = 0; i < nitems(pll_clks); i++) {
|
||||
clkdef.id = pll_clks[i].id;
|
||||
clkdef.name = pll_clks[i].name;
|
||||
prci_pll_register(sc, &clkdef, pll_clks[i].reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the fixed clock "tlclk".
|
||||
*
|
||||
* If an older device tree is being used, tlclk may appear as its own
|
||||
* entity in the device tree, under soc/tlclk. If this is the case it
|
||||
* will be registered automatically by the fixed_clk driver, and the
|
||||
* version we register here will be an unreferenced duplicate.
|
||||
*/
|
||||
clknode_fixed_register(sc->clkdom, &tlclk_def);
|
||||
|
||||
error = clkdom_finit(sc->clkdom);
|
||||
if (error)
|
||||
|
@ -65,8 +65,6 @@ struct uio;
|
||||
|
||||
typedef int (*mmap_check_fp_fn)(struct file *, int, int, int);
|
||||
|
||||
int kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg,
|
||||
size_t buflen, size_t path_max);
|
||||
int kern_accept(struct thread *td, int s, struct sockaddr **name,
|
||||
socklen_t *namelen, struct file **fp);
|
||||
int kern_accept4(struct thread *td, int s, struct sockaddr **name,
|
||||
|
@ -631,7 +631,8 @@ int insmntque(struct vnode *vp, struct mount *mp);
|
||||
u_quad_t init_va_filerev(void);
|
||||
int speedup_syncer(void);
|
||||
int vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf,
|
||||
u_int *buflen);
|
||||
size_t *buflen);
|
||||
int vn_getcwd(struct thread *td, char *buf, char **retbuf, size_t *buflen);
|
||||
int vn_fullpath(struct thread *td, struct vnode *vn,
|
||||
char **retbuf, char **freebuf);
|
||||
int vn_fullpath_global(struct thread *td, struct vnode *vn,
|
||||
|
@ -1155,23 +1155,6 @@ vm_page_xunbusy_hard_unchecked(vm_page_t m)
|
||||
vm_page_xunbusy_hard_tail(m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Avoid releasing and reacquiring the same page lock.
|
||||
*/
|
||||
void
|
||||
vm_page_change_lock(vm_page_t m, struct mtx **mtx)
|
||||
{
|
||||
struct mtx *mtx1;
|
||||
|
||||
mtx1 = vm_page_lockptr(m);
|
||||
if (*mtx == mtx1)
|
||||
return;
|
||||
if (*mtx != NULL)
|
||||
mtx_unlock(*mtx);
|
||||
*mtx = mtx1;
|
||||
mtx_lock(mtx1);
|
||||
}
|
||||
|
||||
/*
|
||||
* vm_page_unhold_pages:
|
||||
*
|
||||
@ -2444,7 +2427,6 @@ vm_page_t
|
||||
vm_page_scan_contig(u_long npages, vm_page_t m_start, vm_page_t m_end,
|
||||
u_long alignment, vm_paddr_t boundary, int options)
|
||||
{
|
||||
struct mtx *m_mtx;
|
||||
vm_object_t object;
|
||||
vm_paddr_t pa;
|
||||
vm_page_t m, m_run;
|
||||
@ -2458,7 +2440,6 @@ vm_page_scan_contig(u_long npages, vm_page_t m_start, vm_page_t m_end,
|
||||
KASSERT(powerof2(boundary), ("boundary is not a power of 2"));
|
||||
m_run = NULL;
|
||||
run_len = 0;
|
||||
m_mtx = NULL;
|
||||
for (m = m_start; m < m_end && run_len < npages; m += m_inc) {
|
||||
KASSERT((m->flags & PG_MARKER) == 0,
|
||||
("page %p is PG_MARKER", m));
|
||||
@ -2489,9 +2470,8 @@ vm_page_scan_contig(u_long npages, vm_page_t m_start, vm_page_t m_end,
|
||||
} else
|
||||
KASSERT(m_run != NULL, ("m_run == NULL"));
|
||||
|
||||
vm_page_change_lock(m, &m_mtx);
|
||||
m_inc = 1;
|
||||
retry:
|
||||
m_inc = 1;
|
||||
if (vm_page_wired(m))
|
||||
run_ext = 0;
|
||||
#if VM_NRESERVLEVEL > 0
|
||||
@ -2504,23 +2484,17 @@ vm_page_scan_contig(u_long npages, vm_page_t m_start, vm_page_t m_end,
|
||||
pa);
|
||||
}
|
||||
#endif
|
||||
else if ((object = m->object) != NULL) {
|
||||
else if ((object =
|
||||
(vm_object_t)atomic_load_ptr(&m->object)) != NULL) {
|
||||
/*
|
||||
* The page is considered eligible for relocation if
|
||||
* and only if it could be laundered or reclaimed by
|
||||
* the page daemon.
|
||||
*/
|
||||
if (!VM_OBJECT_TRYRLOCK(object)) {
|
||||
mtx_unlock(m_mtx);
|
||||
VM_OBJECT_RLOCK(object);
|
||||
mtx_lock(m_mtx);
|
||||
if (m->object != object) {
|
||||
/*
|
||||
* The page may have been freed.
|
||||
*/
|
||||
VM_OBJECT_RUNLOCK(object);
|
||||
goto retry;
|
||||
}
|
||||
VM_OBJECT_RLOCK(object);
|
||||
if (object != m->object) {
|
||||
VM_OBJECT_RUNLOCK(object);
|
||||
goto retry;
|
||||
}
|
||||
/* Don't care: PG_NODUMP, PG_ZERO. */
|
||||
if (object->type != OBJT_DEFAULT &&
|
||||
@ -2537,8 +2511,7 @@ vm_page_scan_contig(u_long npages, vm_page_t m_start, vm_page_t m_end,
|
||||
vm_reserv_size(level)) - pa);
|
||||
#endif
|
||||
} else if (object->memattr == VM_MEMATTR_DEFAULT &&
|
||||
vm_page_queue(m) != PQ_NONE && !vm_page_busied(m) &&
|
||||
!vm_page_wired(m)) {
|
||||
vm_page_queue(m) != PQ_NONE && !vm_page_busied(m)) {
|
||||
/*
|
||||
* The page is allocated but eligible for
|
||||
* relocation. Extend the current run by one
|
||||
@ -2605,8 +2578,6 @@ vm_page_scan_contig(u_long npages, vm_page_t m_start, vm_page_t m_end,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_mtx != NULL)
|
||||
mtx_unlock(m_mtx);
|
||||
if (run_len >= npages)
|
||||
return (m_run);
|
||||
return (NULL);
|
||||
@ -2634,7 +2605,6 @@ vm_page_reclaim_run(int req_class, int domain, u_long npages, vm_page_t m_run,
|
||||
vm_paddr_t high)
|
||||
{
|
||||
struct vm_domain *vmd;
|
||||
struct mtx *m_mtx;
|
||||
struct spglist free;
|
||||
vm_object_t object;
|
||||
vm_paddr_t pa;
|
||||
@ -2647,42 +2617,28 @@ vm_page_reclaim_run(int req_class, int domain, u_long npages, vm_page_t m_run,
|
||||
error = 0;
|
||||
m = m_run;
|
||||
m_end = m_run + npages;
|
||||
m_mtx = NULL;
|
||||
for (; error == 0 && m < m_end; m++) {
|
||||
KASSERT((m->flags & (PG_FICTITIOUS | PG_MARKER)) == 0,
|
||||
("page %p is PG_FICTITIOUS or PG_MARKER", m));
|
||||
|
||||
/*
|
||||
* Avoid releasing and reacquiring the same page lock.
|
||||
*/
|
||||
vm_page_change_lock(m, &m_mtx);
|
||||
retry:
|
||||
/*
|
||||
* Racily check for wirings. Races are handled below.
|
||||
* Racily check for wirings. Races are handled once the object
|
||||
* lock is held and the page is unmapped.
|
||||
*/
|
||||
if (vm_page_wired(m))
|
||||
error = EBUSY;
|
||||
else if ((object = m->object) != NULL) {
|
||||
else if ((object =
|
||||
(vm_object_t)atomic_load_ptr(&m->object)) != NULL) {
|
||||
/*
|
||||
* The page is relocated if and only if it could be
|
||||
* laundered or reclaimed by the page daemon.
|
||||
*/
|
||||
if (!VM_OBJECT_TRYWLOCK(object)) {
|
||||
mtx_unlock(m_mtx);
|
||||
VM_OBJECT_WLOCK(object);
|
||||
mtx_lock(m_mtx);
|
||||
if (m->object != object) {
|
||||
/*
|
||||
* The page may have been freed.
|
||||
*/
|
||||
VM_OBJECT_WUNLOCK(object);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
VM_OBJECT_WLOCK(object);
|
||||
/* Don't care: PG_NODUMP, PG_ZERO. */
|
||||
if (object->type != OBJT_DEFAULT &&
|
||||
if (m->object != object ||
|
||||
(object->type != OBJT_DEFAULT &&
|
||||
object->type != OBJT_SWAP &&
|
||||
object->type != OBJT_VNODE)
|
||||
object->type != OBJT_VNODE))
|
||||
error = EINVAL;
|
||||
else if (object->memattr != VM_MEMATTR_DEFAULT)
|
||||
error = EINVAL;
|
||||
@ -2781,7 +2737,6 @@ vm_page_reclaim_run(int req_class, int domain, u_long npages, vm_page_t m_run,
|
||||
* The new page must be deactivated
|
||||
* before the object is unlocked.
|
||||
*/
|
||||
vm_page_change_lock(m_new, &m_mtx);
|
||||
vm_page_deactivate(m_new);
|
||||
} else {
|
||||
m->flags &= ~PG_ZERO;
|
||||
@ -2821,8 +2776,6 @@ vm_page_reclaim_run(int req_class, int domain, u_long npages, vm_page_t m_run,
|
||||
error = EINVAL;
|
||||
}
|
||||
}
|
||||
if (m_mtx != NULL)
|
||||
mtx_unlock(m_mtx);
|
||||
if ((m = SLIST_FIRST(&free)) != NULL) {
|
||||
int cnt;
|
||||
|
||||
|
@ -609,7 +609,6 @@ vm_page_t vm_page_alloc_freelist(int, int);
|
||||
vm_page_t vm_page_alloc_freelist_domain(int, int, int);
|
||||
void vm_page_bits_set(vm_page_t m, vm_page_bits_t *bits, vm_page_bits_t set);
|
||||
bool vm_page_blacklist_add(vm_paddr_t pa, bool verbose);
|
||||
void vm_page_change_lock(vm_page_t m, struct mtx **mtx);
|
||||
vm_page_t vm_page_grab (vm_object_t, vm_pindex_t, int);
|
||||
int vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags,
|
||||
vm_page_t *ma, int count);
|
||||
|
@ -88,8 +88,12 @@ struct hwp_softc {
|
||||
bool hwp_activity_window;
|
||||
bool hwp_pref_ctrl;
|
||||
bool hwp_pkg_ctrl;
|
||||
bool hwp_pkg_ctrl_en;
|
||||
bool hwp_perf_bias;
|
||||
bool hwp_perf_bias_cached;
|
||||
|
||||
uint64_t req; /* Cached copy of last request */
|
||||
uint64_t req; /* Cached copy of HWP_REQUEST */
|
||||
uint64_t hwp_energy_perf_bias; /* Cache PERF_BIAS */
|
||||
|
||||
uint8_t high;
|
||||
uint8_t guaranteed;
|
||||
@ -108,6 +112,11 @@ DRIVER_MODULE(hwpstate_intel, cpu, hwpstate_intel_driver,
|
||||
hwpstate_intel_devclass, NULL, NULL);
|
||||
MODULE_VERSION(hwpstate_intel, 1);
|
||||
|
||||
static bool hwpstate_pkg_ctrl_enable = true;
|
||||
SYSCTL_BOOL(_machdep, OID_AUTO, hwpstate_pkg_ctrl, CTLFLAG_RDTUN,
|
||||
&hwpstate_pkg_ctrl_enable, 0,
|
||||
"Set 1 (default) to enable package-level control, 0 to disable");
|
||||
|
||||
static int
|
||||
intel_hwp_dump_sysctl_handler(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
@ -215,16 +224,41 @@ raw_to_percent(int x)
|
||||
return (round10(x * 1000 / 0xff));
|
||||
}
|
||||
|
||||
/* Range of MSR_IA32_ENERGY_PERF_BIAS is more limited: 0-0xf. */
|
||||
static inline int
|
||||
percent_to_raw_perf_bias(int x)
|
||||
{
|
||||
/*
|
||||
* Round up so that raw values present as nice round human numbers and
|
||||
* also round-trip to the same raw value.
|
||||
*/
|
||||
MPASS(x <= 100 && x >= 0);
|
||||
return (((0xf * x) + 50) / 100);
|
||||
}
|
||||
|
||||
static inline int
|
||||
raw_to_percent_perf_bias(int x)
|
||||
{
|
||||
/* Rounding to nice human numbers despite a step interval of 6.67%. */
|
||||
MPASS(x <= 0xf && x >= 0);
|
||||
return (((x * 20) / 0xf) * 5);
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_epp_select(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct hwp_softc *sc;
|
||||
device_t dev;
|
||||
struct pcpu *pc;
|
||||
uint64_t requested;
|
||||
uint64_t epb;
|
||||
uint32_t val;
|
||||
int ret;
|
||||
|
||||
dev = oidp->oid_arg1;
|
||||
sc = device_get_softc(dev);
|
||||
if (!sc->hwp_pref_ctrl && !sc->hwp_perf_bias)
|
||||
return (ENODEV);
|
||||
|
||||
pc = cpu_get_pcpu(dev);
|
||||
if (pc == NULL)
|
||||
return (ENXIO);
|
||||
@ -233,9 +267,26 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS)
|
||||
sched_bind(curthread, pc->pc_cpuid);
|
||||
thread_unlock(curthread);
|
||||
|
||||
rdmsr_safe(MSR_IA32_HWP_REQUEST, &requested);
|
||||
val = (requested & IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE) >> 24;
|
||||
val = raw_to_percent(val);
|
||||
if (sc->hwp_pref_ctrl) {
|
||||
val = (sc->req & IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE) >> 24;
|
||||
val = raw_to_percent(val);
|
||||
} else {
|
||||
/*
|
||||
* If cpuid indicates EPP is not supported, the HWP controller
|
||||
* uses MSR_IA32_ENERGY_PERF_BIAS instead (Intel SDM §14.4.4).
|
||||
* This register is per-core (but not HT).
|
||||
*/
|
||||
if (!sc->hwp_perf_bias_cached) {
|
||||
ret = rdmsr_safe(MSR_IA32_ENERGY_PERF_BIAS, &epb);
|
||||
if (ret)
|
||||
goto out;
|
||||
sc->hwp_energy_perf_bias = epb;
|
||||
sc->hwp_perf_bias_cached = true;
|
||||
}
|
||||
val = sc->hwp_energy_perf_bias &
|
||||
IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK;
|
||||
val = raw_to_percent_perf_bias(val);
|
||||
}
|
||||
|
||||
MPASS(val >= 0 && val <= 100);
|
||||
|
||||
@ -248,12 +299,27 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS)
|
||||
goto out;
|
||||
}
|
||||
|
||||
val = percent_to_raw(val);
|
||||
if (sc->hwp_pref_ctrl) {
|
||||
val = percent_to_raw(val);
|
||||
|
||||
requested &= ~IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE;
|
||||
requested |= val << 24;
|
||||
sc->req =
|
||||
((sc->req & ~IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE)
|
||||
| (val << 24u));
|
||||
|
||||
wrmsr_safe(MSR_IA32_HWP_REQUEST, requested);
|
||||
if (sc->hwp_pkg_ctrl_en)
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req);
|
||||
else
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req);
|
||||
} else {
|
||||
val = percent_to_raw_perf_bias(val);
|
||||
MPASS((val & ~IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK) == 0);
|
||||
|
||||
sc->hwp_energy_perf_bias =
|
||||
((sc->hwp_energy_perf_bias &
|
||||
~IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK) | val);
|
||||
ret = wrmsr_safe(MSR_IA32_ENERGY_PERF_BIAS,
|
||||
sc->hwp_energy_perf_bias);
|
||||
}
|
||||
|
||||
out:
|
||||
thread_lock(curthread);
|
||||
@ -266,8 +332,6 @@ sysctl_epp_select(SYSCTL_HANDLER_ARGS)
|
||||
void
|
||||
intel_hwpstate_identify(driver_t *driver, device_t parent)
|
||||
{
|
||||
uint32_t regs[4];
|
||||
|
||||
if (device_find_child(parent, "hwpstate_intel", -1) != NULL)
|
||||
return;
|
||||
|
||||
@ -277,17 +341,6 @@ intel_hwpstate_identify(driver_t *driver, device_t parent)
|
||||
if (resource_disabled("hwpstate_intel", 0))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Intel SDM 14.4.1 (HWP Programming Interfaces):
|
||||
* The CPUID instruction allows software to discover the presence of
|
||||
* HWP support in an Intel processor. Specifically, execute CPUID
|
||||
* instruction with EAX=06H as input will return 5 bit flags covering
|
||||
* the following aspects in bits 7 through 11 of CPUID.06H:EAX.
|
||||
*/
|
||||
|
||||
if (cpu_high < 6)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Intel SDM 14.4.1 (HWP Programming Interfaces):
|
||||
* Availability of HWP baseline resource and capability,
|
||||
@ -295,9 +348,7 @@ intel_hwpstate_identify(driver_t *driver, device_t parent)
|
||||
* architectural MSRs: IA32_PM_ENABLE, IA32_HWP_CAPABILITIES,
|
||||
* IA32_HWP_REQUEST, IA32_HWP_STATUS.
|
||||
*/
|
||||
|
||||
do_cpuid(6, regs);
|
||||
if ((regs[0] & CPUTPM1_HWP) == 0)
|
||||
if ((cpu_power_eax & CPUTPM1_HWP) == 0)
|
||||
return;
|
||||
|
||||
if (BUS_ADD_CHILD(parent, 10, "hwpstate_intel", -1) == NULL)
|
||||
@ -315,7 +366,6 @@ intel_hwpstate_probe(device_t dev)
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
/* FIXME: Need to support PKG variant */
|
||||
static int
|
||||
set_autonomous_hwp(struct hwp_softc *sc)
|
||||
{
|
||||
@ -337,19 +387,39 @@ set_autonomous_hwp(struct hwp_softc *sc)
|
||||
/* XXX: Many MSRs aren't readable until feature is enabled */
|
||||
ret = wrmsr_safe(MSR_IA32_PM_ENABLE, 1);
|
||||
if (ret) {
|
||||
/*
|
||||
* This is actually a package-level MSR, and only the first
|
||||
* write is not ignored. So it is harmless to enable it across
|
||||
* all devices, and this allows us not to care especially in
|
||||
* which order cores (and packages) are probed. This error
|
||||
* condition should not happen given we gate on the HWP CPUID
|
||||
* feature flag, if the Intel SDM is correct.
|
||||
*/
|
||||
device_printf(dev, "Failed to enable HWP for cpu%d (%d)\n",
|
||||
pc->pc_cpuid, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = rdmsr_safe(MSR_IA32_HWP_REQUEST, &sc->req);
|
||||
if (ret)
|
||||
return (ret);
|
||||
if (ret) {
|
||||
device_printf(dev,
|
||||
"Failed to read HWP request MSR for cpu%d (%d)\n",
|
||||
pc->pc_cpuid, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = rdmsr_safe(MSR_IA32_HWP_CAPABILITIES, &caps);
|
||||
if (ret)
|
||||
return (ret);
|
||||
if (ret) {
|
||||
device_printf(dev,
|
||||
"Failed to read HWP capabilities MSR for cpu%d (%d)\n",
|
||||
pc->pc_cpuid, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* High and low are static; "guaranteed" is dynamic; and efficient is
|
||||
* also dynamic.
|
||||
*/
|
||||
sc->high = IA32_HWP_CAPABILITIES_HIGHEST_PERFORMANCE(caps);
|
||||
sc->guaranteed = IA32_HWP_CAPABILITIES_GUARANTEED_PERFORMANCE(caps);
|
||||
sc->efficient = IA32_HWP_CAPABILITIES_EFFICIENT_PERFORMANCE(caps);
|
||||
@ -369,11 +439,30 @@ set_autonomous_hwp(struct hwp_softc *sc)
|
||||
sc->req &= ~IA32_HWP_REQUEST_MAXIMUM_PERFORMANCE;
|
||||
sc->req |= sc->high << 8;
|
||||
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req);
|
||||
/* If supported, request package-level control for this CPU. */
|
||||
if (sc->hwp_pkg_ctrl_en)
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req |
|
||||
IA32_HWP_REQUEST_PACKAGE_CONTROL);
|
||||
else
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req);
|
||||
if (ret) {
|
||||
device_printf(dev,
|
||||
"Failed to setup autonomous HWP for cpu%d (file a bug)\n",
|
||||
pc->pc_cpuid);
|
||||
"Failed to setup%s autonomous HWP for cpu%d\n",
|
||||
sc->hwp_pkg_ctrl_en ? " PKG" : "", pc->pc_cpuid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If supported, write the PKG-wide control MSR. */
|
||||
if (sc->hwp_pkg_ctrl_en) {
|
||||
/*
|
||||
* "The structure of the IA32_HWP_REQUEST_PKG MSR
|
||||
* (package-level) is identical to the IA32_HWP_REQUEST MSR
|
||||
* with the exception of the Package Control field, which does
|
||||
* not exist." (Intel SDM §14.4.4)
|
||||
*/
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req);
|
||||
device_printf(dev,
|
||||
"Failed to set autonomous HWP for package\n");
|
||||
}
|
||||
|
||||
out:
|
||||
@ -388,22 +477,28 @@ static int
|
||||
intel_hwpstate_attach(device_t dev)
|
||||
{
|
||||
struct hwp_softc *sc;
|
||||
uint32_t regs[4];
|
||||
int ret;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
|
||||
do_cpuid(6, regs);
|
||||
if (regs[0] & CPUTPM1_HWP_NOTIFICATION)
|
||||
/* eax */
|
||||
if (cpu_power_eax & CPUTPM1_HWP_NOTIFICATION)
|
||||
sc->hwp_notifications = true;
|
||||
if (regs[0] & CPUTPM1_HWP_ACTIVITY_WINDOW)
|
||||
if (cpu_power_eax & CPUTPM1_HWP_ACTIVITY_WINDOW)
|
||||
sc->hwp_activity_window = true;
|
||||
if (regs[0] & CPUTPM1_HWP_PERF_PREF)
|
||||
if (cpu_power_eax & CPUTPM1_HWP_PERF_PREF)
|
||||
sc->hwp_pref_ctrl = true;
|
||||
if (regs[0] & CPUTPM1_HWP_PKG)
|
||||
if (cpu_power_eax & CPUTPM1_HWP_PKG)
|
||||
sc->hwp_pkg_ctrl = true;
|
||||
|
||||
/* Allow administrators to disable pkg-level control. */
|
||||
sc->hwp_pkg_ctrl_en = (sc->hwp_pkg_ctrl && hwpstate_pkg_ctrl_enable);
|
||||
|
||||
/* ecx */
|
||||
if (cpu_power_ecx & CPUID_PERF_BIAS)
|
||||
sc->hwp_perf_bias = true;
|
||||
|
||||
ret = set_autonomous_hwp(sc);
|
||||
if (ret)
|
||||
return (ret);
|
||||
@ -503,11 +598,34 @@ intel_hwpstate_resume(device_t dev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req);
|
||||
if (sc->hwp_pkg_ctrl_en)
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req |
|
||||
IA32_HWP_REQUEST_PACKAGE_CONTROL);
|
||||
else
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST, sc->req);
|
||||
if (ret) {
|
||||
device_printf(dev,
|
||||
"Failed to setup autonomous HWP for cpu%d after suspend\n",
|
||||
pc->pc_cpuid);
|
||||
"Failed to set%s autonomous HWP for cpu%d after suspend\n",
|
||||
sc->hwp_pkg_ctrl_en ? " PKG" : "", pc->pc_cpuid);
|
||||
goto out;
|
||||
}
|
||||
if (sc->hwp_pkg_ctrl_en) {
|
||||
ret = wrmsr_safe(MSR_IA32_HWP_REQUEST_PKG, sc->req);
|
||||
if (ret) {
|
||||
device_printf(dev,
|
||||
"Failed to set autonomous HWP for package after "
|
||||
"suspend\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (!sc->hwp_pref_ctrl && sc->hwp_perf_bias_cached) {
|
||||
ret = wrmsr_safe(MSR_IA32_ENERGY_PERF_BIAS,
|
||||
sc->hwp_energy_perf_bias);
|
||||
if (ret) {
|
||||
device_printf(dev,
|
||||
"Failed to set energy perf bias for cpu%d after "
|
||||
"suspend\n", pc->pc_cpuid);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -566,6 +566,7 @@
|
||||
#define MSR_IA32_TEMPERATURE_TARGET 0x1a2
|
||||
#define MSR_TURBO_RATIO_LIMIT 0x1ad
|
||||
#define MSR_TURBO_RATIO_LIMIT1 0x1ae
|
||||
#define MSR_IA32_ENERGY_PERF_BIAS 0x1b0
|
||||
#define MSR_DEBUGCTLMSR 0x1d9
|
||||
#define MSR_LASTBRANCHFROMIP 0x1db
|
||||
#define MSR_LASTBRANCHTOIP 0x1dc
|
||||
@ -811,6 +812,9 @@
|
||||
#define IA32_HWP_REQUEST_MAXIMUM_PERFORMANCE (0xffULL << 8)
|
||||
#define IA32_HWP_MINIMUM_PERFORMANCE (0xffULL << 0)
|
||||
|
||||
/* MSR IA32_ENERGY_PERF_BIAS */
|
||||
#define IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK (0xfULL << 0)
|
||||
|
||||
/*
|
||||
* PAT modes.
|
||||
*/
|
||||
|
@ -119,9 +119,9 @@ u_int cpu_mon_min_size; /* MONITOR minimum range size, bytes */
|
||||
u_int cpu_mon_max_size; /* MONITOR minimum range size, bytes */
|
||||
u_int cpu_maxphyaddr; /* Max phys addr width in bits */
|
||||
u_int cpu_power_eax; /* 06H: Power management leaf, %eax */
|
||||
u_int cpu_power_ebx; /* 06H: Power management leaf, %eax */
|
||||
u_int cpu_power_ecx; /* 06H: Power management leaf, %eax */
|
||||
u_int cpu_power_edx; /* 06H: Power management leaf, %eax */
|
||||
u_int cpu_power_ebx; /* 06H: Power management leaf, %ebx */
|
||||
u_int cpu_power_ecx; /* 06H: Power management leaf, %ecx */
|
||||
u_int cpu_power_edx; /* 06H: Power management leaf, %edx */
|
||||
char machine[] = MACHINE;
|
||||
|
||||
SYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD,
|
||||
|
@ -53,7 +53,7 @@ ATF_TC_BODY(params, tc)
|
||||
int s;
|
||||
|
||||
s = kldload("if_epair");
|
||||
if (s != 0 && errno != EEXIST)
|
||||
if (s == -1 && errno != EEXIST)
|
||||
atf_tc_fail("Failed to load if_epair");
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user