MFhead @ r275589

This commit is contained in:
Enji Cooper 2014-12-08 03:36:43 +00:00
commit 2c3f939cab
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/building-blocks/; revision=275590
68 changed files with 1498 additions and 2881 deletions

View File

@ -68,6 +68,7 @@
#ifdef sun
#include <aclutils.h>
#include <directory.h>
#include <idmap.h>
#endif
#include "zfs_iter.h"
@ -2390,10 +2391,9 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space)
/* SMB */
char sid[ZFS_MAXNAMELEN + 32];
uid_t id;
uint64_t classes;
#ifdef sun
int err;
directory_error_t e;
int flag = IDMAP_REQ_FLG_USE_CACHE;
#endif
smbentity = B_TRUE;
@ -2416,10 +2416,13 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space)
if (err == 0) {
rid = id;
if (!cb->cb_sid2posix) {
e = directory_name_from_sid(NULL, sid, &name,
&classes);
if (e != NULL)
directory_error_free(e);
if (type == USTYPE_SMB_USR) {
(void) idmap_getwinnamebyuid(rid, flag,
&name, NULL);
} else {
(void) idmap_getwinnamebygid(rid, flag,
&name, NULL);
}
if (name == NULL)
name = sid;
}

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
#ifndef _LIBNVPAIR_H
@ -46,6 +47,7 @@ extern int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *,
char **);
extern void nvlist_print(FILE *, nvlist_t *);
extern int nvlist_print_json(FILE *, nvlist_t *);
extern void dump_nvlist(nvlist_t *, int);
/*

View File

@ -0,0 +1,403 @@
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright (c) 2014, Joyent, Inc.
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <wchar.h>
#include <sys/debug.h>
#include "libnvpair.h"
#define FPRINTF(fp, ...) \
do { \
if (fprintf(fp, __VA_ARGS__) < 0) \
return (-1); \
} while (0)
/*
* When formatting a string for JSON output we must escape certain characters,
* as described in RFC4627. This applies to both member names and
* DATA_TYPE_STRING values.
*
* This function will only operate correctly if the following conditions are
* met:
*
* 1. The input String is encoded in the current locale.
*
* 2. The current locale includes the Basic Multilingual Plane (plane 0)
* as defined in the Unicode standard.
*
* The output will be entirely 7-bit ASCII (as a subset of UTF-8) with all
* representable Unicode characters included in their escaped numeric form.
*/
static int
nvlist_print_json_string(FILE *fp, const char *input)
{
mbstate_t mbr;
wchar_t c;
size_t sz;
bzero(&mbr, sizeof (mbr));
FPRINTF(fp, "\"");
while ((sz = mbrtowc(&c, input, MB_CUR_MAX, &mbr)) > 0) {
switch (c) {
case '"':
FPRINTF(fp, "\\\"");
break;
case '\n':
FPRINTF(fp, "\\n");
break;
case '\r':
FPRINTF(fp, "\\r");
break;
case '\\':
FPRINTF(fp, "\\\\");
break;
case '\f':
FPRINTF(fp, "\\f");
break;
case '\t':
FPRINTF(fp, "\\t");
break;
case '\b':
FPRINTF(fp, "\\b");
break;
default:
if ((c >= 0x00 && c <= 0x1f) ||
(c > 0x7f && c <= 0xffff)) {
/*
* Render both Control Characters and Unicode
* characters in the Basic Multilingual Plane
* as JSON-escaped multibyte characters.
*/
FPRINTF(fp, "\\u%04x", (int)(0xffff & c));
} else if (c >= 0x20 && c <= 0x7f) {
/*
* Render other 7-bit ASCII characters directly
* and drop other, unrepresentable characters.
*/
FPRINTF(fp, "%c", (int)(0xff & c));
}
break;
}
input += sz;
}
if (sz == (size_t)-1 || sz == (size_t)-2) {
/*
* We last read an invalid multibyte character sequence,
* so return an error.
*/
return (-1);
}
FPRINTF(fp, "\"");
return (0);
}
/*
* Dump a JSON-formatted representation of an nvlist to the provided FILE *.
* This routine does not output any new-lines or additional whitespace other
* than that contained in strings, nor does it call fflush(3C).
*/
int
nvlist_print_json(FILE *fp, nvlist_t *nvl)
{
nvpair_t *curr;
boolean_t first = B_TRUE;
FPRINTF(fp, "{");
for (curr = nvlist_next_nvpair(nvl, NULL); curr;
curr = nvlist_next_nvpair(nvl, curr)) {
data_type_t type = nvpair_type(curr);
if (!first)
FPRINTF(fp, ",");
else
first = B_FALSE;
if (nvlist_print_json_string(fp, nvpair_name(curr)) == -1)
return (-1);
FPRINTF(fp, ":");
switch (type) {
case DATA_TYPE_STRING: {
char *string = fnvpair_value_string(curr);
if (nvlist_print_json_string(fp, string) == -1)
return (-1);
break;
}
case DATA_TYPE_BOOLEAN: {
FPRINTF(fp, "true");
break;
}
case DATA_TYPE_BOOLEAN_VALUE: {
FPRINTF(fp, "%s", fnvpair_value_boolean_value(curr) ==
B_TRUE ? "true" : "false");
break;
}
case DATA_TYPE_BYTE: {
FPRINTF(fp, "%hhu", fnvpair_value_byte(curr));
break;
}
case DATA_TYPE_INT8: {
FPRINTF(fp, "%hhd", fnvpair_value_int8(curr));
break;
}
case DATA_TYPE_UINT8: {
FPRINTF(fp, "%hhu", fnvpair_value_uint8_t(curr));
break;
}
case DATA_TYPE_INT16: {
FPRINTF(fp, "%hd", fnvpair_value_int16(curr));
break;
}
case DATA_TYPE_UINT16: {
FPRINTF(fp, "%hu", fnvpair_value_uint16(curr));
break;
}
case DATA_TYPE_INT32: {
FPRINTF(fp, "%d", fnvpair_value_int32(curr));
break;
}
case DATA_TYPE_UINT32: {
FPRINTF(fp, "%u", fnvpair_value_uint32(curr));
break;
}
case DATA_TYPE_INT64: {
FPRINTF(fp, "%lld",
(long long)fnvpair_value_int64(curr));
break;
}
case DATA_TYPE_UINT64: {
FPRINTF(fp, "%llu",
(unsigned long long)fnvpair_value_uint64(curr));
break;
}
case DATA_TYPE_HRTIME: {
hrtime_t val;
VERIFY0(nvpair_value_hrtime(curr, &val));
FPRINTF(fp, "%llu", (unsigned long long)val);
break;
}
case DATA_TYPE_DOUBLE: {
double val;
VERIFY0(nvpair_value_double(curr, &val));
FPRINTF(fp, "%f", val);
break;
}
case DATA_TYPE_NVLIST: {
if (nvlist_print_json(fp,
fnvpair_value_nvlist(curr)) == -1)
return (-1);
break;
}
case DATA_TYPE_STRING_ARRAY: {
char **val;
uint_t valsz, i;
VERIFY0(nvpair_value_string_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
if (nvlist_print_json_string(fp, val[i]) == -1)
return (-1);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_NVLIST_ARRAY: {
nvlist_t **val;
uint_t valsz, i;
VERIFY0(nvpair_value_nvlist_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
if (nvlist_print_json(fp, val[i]) == -1)
return (-1);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_BOOLEAN_ARRAY: {
boolean_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_boolean_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, val[i] == B_TRUE ?
"true" : "false");
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_BYTE_ARRAY: {
uchar_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_byte_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%hhu", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_UINT8_ARRAY: {
uint8_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint8_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%hhu", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_INT8_ARRAY: {
int8_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int8_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%hhd", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_UINT16_ARRAY: {
uint16_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint16_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%hu", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_INT16_ARRAY: {
int16_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int16_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%hd", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_UINT32_ARRAY: {
uint32_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint32_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%u", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_INT32_ARRAY: {
int32_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int32_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%d", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_UINT64_ARRAY: {
uint64_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint64_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%llu",
(unsigned long long)val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_INT64_ARRAY: {
int64_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int64_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%lld", (long long)val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_UNKNOWN:
return (-1);
}
}
FPRINTF(fp, "}");
return (0);
}

View File

@ -2615,7 +2615,7 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
boolean_t isuser;
domain[0] = '\0';
*ridp = 0;
/* Figure out the property type ({user|group}{quota|space}) */
for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) {
if (strncmp(propname, zfs_userquota_prop_prefixes[type],
@ -2637,23 +2637,46 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
* It's a SID name (eg "user@domain") that needs to be
* turned into S-1-domainID-RID.
*/
directory_error_t e;
int flag = 0;
idmap_stat stat, map_stat;
uid_t pid;
idmap_rid_t rid;
idmap_get_handle_t *gh = NULL;
stat = idmap_get_create(&gh);
if (stat != IDMAP_SUCCESS) {
idmap_get_destroy(gh);
return (ENOMEM);
}
if (zoned && getzoneid() == GLOBAL_ZONEID)
return (ENOENT);
if (isuser) {
e = directory_sid_from_user_name(NULL,
cp, &numericsid);
stat = idmap_getuidbywinname(cp, NULL, flag, &pid);
if (stat < 0)
return (ENOENT);
stat = idmap_get_sidbyuid(gh, pid, flag, &numericsid,
&rid, &map_stat);
} else {
e = directory_sid_from_group_name(NULL,
cp, &numericsid);
stat = idmap_getgidbywinname(cp, NULL, flag, &pid);
if (stat < 0)
return (ENOENT);
stat = idmap_get_sidbygid(gh, pid, flag, &numericsid,
&rid, &map_stat);
}
if (e != NULL) {
directory_error_free(e);
if (stat < 0) {
idmap_get_destroy(gh);
return (ENOENT);
}
stat = idmap_get_mappings(gh);
idmap_get_destroy(gh);
if (stat < 0) {
return (ENOENT);
}
if (numericsid == NULL)
return (ENOENT);
cp = numericsid;
*ridp = rid;
/* will be further decoded below */
#else /* !sun */
return (ENOENT);
@ -2663,12 +2686,15 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
if (strncmp(cp, "S-1-", 4) == 0) {
/* It's a numeric SID (eg "S-1-234-567-89") */
(void) strlcpy(domain, cp, domainlen);
cp = strrchr(domain, '-');
*cp = '\0';
cp++;
errno = 0;
*ridp = strtoull(cp, &end, 10);
if (*ridp == 0) {
cp = strrchr(domain, '-');
*cp = '\0';
cp++;
*ridp = strtoull(cp, &end, 10);
} else {
end = "";
}
if (numericsid) {
free(numericsid);
numericsid = NULL;

View File

@ -26,8 +26,6 @@
#ifndef _CTFTOOLS_H
#define _CTFTOOLS_H
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Functions and data structures used in the manipulation of stabs and CTF data
*/
@ -39,6 +37,8 @@
#include <gelf.h>
#include <pthread.h>
#include <sys/ccompile.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -435,8 +435,8 @@ int streq(const char *, const char *);
int findelfsecidx(Elf *, const char *, const char *);
size_t elf_ptrsz(Elf *);
char *mktmpname(const char *, const char *);
void terminate(const char *, ...);
void aborterr(const char *, ...);
void terminate(const char *, ...) __NORETURN;
void aborterr(const char *, ...) __NORETURN;
void set_terminate_cleanup(void (*)(void));
void elfterminate(const char *, const char *, ...);
void warning(const char *, ...);

View File

@ -9,6 +9,7 @@ SRCS= libnvpair.c \
nvpair_alloc_system.c \
nvpair_alloc_fixed.c \
nvpair.c \
nvpair_json.c \
fnvpair.c
WARNS?= 0

View File

@ -6789,7 +6789,11 @@ do_co_reg (void)
{
inst.instruction |= inst.operands[0].reg << 8;
inst.instruction |= inst.operands[1].imm << 21;
inst.instruction |= inst.operands[2].reg << 12;
/* If this is a vector we are using the APSR_nzcv syntax, encode as r15 */
if (inst.operands[2].isvec != 0)
inst.instruction |= 15 << 12;
else
inst.instruction |= inst.operands[2].reg << 12;
inst.instruction |= inst.operands[3].reg << 16;
inst.instruction |= inst.operands[4].reg;
inst.instruction |= inst.operands[5].imm << 5;

View File

@ -115,7 +115,7 @@ __ieee754_j0(double x)
if(ix<0x3f200000) { /* |x| < 2**-13 */
if(huge+x>one) { /* raise inexact if x != 0 */
if(ix<0x3e400000) return one; /* |x|<2**-27 */
else return one - 0.25*x*x;
else return one - x*x/4;
}
}
z = x*x;

View File

@ -69,10 +69,10 @@ __ieee754_j0f(float x)
}
return z;
}
if(ix<0x39000000) { /* |x| < 2**-13 */
if(ix<0x3c000000) { /* |x| < 2**-7 */
if(huge+x>one) { /* raise inexact if x != 0 */
if(ix<0x32000000) return one; /* |x|<2**-27 */
else return one - (float)0.25*x*x;
if(ix<0x39800000) return one; /* |x|<2**-12 */
else return one - x*x/4;
}
}
z = x*x;

View File

@ -8,6 +8,6 @@ S= ${.CURDIR}/../../sys
WARNS?= 3
CFLAGS+= -I$S
MAN= iscsi.conf.5 iscontrol.8
MAN= iscontrol.8
.include <bsd.prog.mk>

View File

@ -126,6 +126,7 @@ josef [label="Josef El-Rayes\njosef@FreeBSD.org\n2004/12/20"]
jpaetzel [label="Josh Paetzel\njpaetzel@FreeBSD.org\n2008/09/05"]
jsa [label="Joseph S. Atkinson\njsa@FreeBSD.org\n2010/07/15"]
jylefort [label="Jean-Yves Lefort\njylefort@FreeBSD.org\n2005/04/12"]
kami [label="Dominic Fandrey\nkami@FreeBSD.org\n2014/09/09"]
kevlo [label="Kevin Lo\nkevlo@FreeBSD.org\n2003/02/21"]
kmoore [label="Kris Moore\nkmoore@FreeBSD.org\n2009/04/14"]
knu [label="Akinori Musha\nknu@FreeBSD.org\n2000/03/22"]
@ -190,6 +191,7 @@ rodrigo [label="Rodrigo Osorio\nrodrigo@FreeBSD.org\n2014/01/15"]
romain [label="Romain Tartiere\nromain@FreeBSD.org\n2010/01/24"]
sahil [label="Sahil Tandon\nsahil@FreeBSD.org\n2010/04/11"]
sat [label="Andrew Pantyukhin\nsat@FreeBSD.org\n2006/05/06"]
sbruno [label="Sean Bruno\nsbruno@FreeBSD.org\n2014/09/14"]
sbz [label="Sofian Brabez\nsbz@FreeBSD.org\n2011/03/14"]
scheidell [label="Michael Scheidell\nscheidell@FreeBSD.org\n2011/11/06"]
sem [label="Sergey Matveychuk\nsem@FreeBSD.org\n2004/07/07"]
@ -256,14 +258,17 @@ avilla -> jhale
avilla -> rakuco
bdrewery -> dbn
bdrewery -> sbruno
bdrewery -> trociny
bapt -> bdrewery
bapt -> eadler
bapt -> grembo
bapt -> jlaffaye
bapt -> marius
bapt -> marino
bapt -> rodrigo
bapt -> sbruno
beat -> decke
beat -> marius
@ -291,6 +296,8 @@ crees -> madpilot
crees -> gblach
crees -> tijl
cs -> kami
culot -> danilo
culot -> jase
culot -> marino
@ -339,6 +346,7 @@ fjoe -> osa
flo -> bar
flo -> jase
flo -> grembo
flz -> garga
flz -> johans
@ -389,6 +397,7 @@ knu -> maho
knu -> nobutaka
knu -> nork
koobs -> kami
koobs -> xmj
krion -> brooks

View File

@ -30,7 +30,7 @@ coresecretary [label="Core Team Secretary\ncore-secretary@FreeBSD.org\nmatthew"]
doccommitters [label="Doc/www Committers\ndoc-committers@FreeBSD.org"]
doceng [label="Documentation Engineering Team\ndoceng@FreeBSD.org\ngjb, blackend,\ngabor, hrs"]
portscommitters [label="Ports Committers\nports-committers@FreeBSD.org"]
portmgr [label="Port Management Team\nportmgr@FreeBSD.org\nantoine, bapt, bdrewery,\ndecke, erwin, mat,\nmiwi, swills, tabthorpe"]
portmgr [label="Port Management Team\nportmgr@FreeBSD.org\nantoine, bapt, bdrewery,\ndecke, erwin, mat, swills"]
portmgrsecretary [label="Port Management Team Secretary\nportmgr-secretary@FreeBSD.org\nculot"]
re [label="Primary Release Engineering Team\nre@FreeBSD.org\nkib, blackend, jpaetzel, hrs, kensmith"]
secteam [label="Security Team\nsecteam@FreeBSD.org\nsimon, qingli, delphij,\nremko, philip, stas, cperciva,\ncsjp, rwatson, miwi, bz"]

View File

@ -25,7 +25,7 @@
.if !target(__<bsd.compiler.mk>__)
__<bsd.compiler.mk>__:
.if !defined(COMPILER_TYPE) && !defined(COMPILER_VERSION)
.if !defined(COMPILER_TYPE) || !defined(COMPILER_VERSION)
_v!= ${CC} --version 2>/dev/null || echo 0.0.0
.if !defined(COMPILER_TYPE)
. if ${CC:T:M*gcc*}

View File

@ -62,7 +62,7 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.cpu arm1136js
.cpu arm1176jz-s
#if 0
#define Invalidate_I_cache(Rtmp1, Rtmp2) \

View File

@ -38,6 +38,8 @@
#include "assym.s"
__FBSDID("$FreeBSD$");
.syntax unified
#ifdef _ARM_ARCH_6
#define GET_PCB(tmp) \
mrc p15, 0, tmp, c13, c0, 4; \
@ -83,7 +85,7 @@ EENTRY_NP(casuword32)
ldrt r5, [r0]
cmp r5, r1
movne r0, r5
streqt r2, [r0]
strteq r2, [r0]
#endif
moveq r0, r1
2:
@ -269,7 +271,7 @@ _C_LABEL(fusubailout):
fusupcbfaulttext:
.asciz "Yikes - no valid PCB during fusuxxx() addr=%08x\n"
.align 0
.align 2
#endif
/*

View File

@ -850,8 +850,13 @@ EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_or, "orr") \
EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_sub, "sub") \
EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_xor, "eor")
#ifdef __clang__
EMIT_ALL_OPS_N(1, uint8_t, "ldrb", "strb", "strbeq")
EMIT_ALL_OPS_N(2, uint16_t, "ldrh", "strh", "strheq")
#else
EMIT_ALL_OPS_N(1, uint8_t, "ldrb", "strb", "streqb")
EMIT_ALL_OPS_N(2, uint16_t, "ldrh", "strh", "streqh")
#endif
EMIT_ALL_OPS_N(4, uint32_t, "ldr", "str", "streq")
#ifndef __clang__

View File

@ -1364,6 +1364,8 @@ ENTRY(memcpy)
strbge r2, [r3], #0x01
strbgt ip, [r3]
RET
/* Place a literal pool here for the above ldr instructions to use */
.ltorg
/*

View File

@ -1171,7 +1171,7 @@ mv_pcib_alloc_msi(device_t dev, device_t child, int count,
for (i = start; i < start + count; i++) {
setbit(&sc->sc_msi_bitmap, i);
irqs[i] = MSI_IRQ + i;
*irqs++ = MSI_IRQ + i;
}
debugf("%s: start: %x count: %x\n", __func__, start, count);

View File

@ -26,7 +26,7 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.arch armv7a
.cpu cortex-a8
.arch_extension sec
/* Issue a smc #0 call */

View File

@ -56,6 +56,7 @@ ENTRY(a4x_bs_r_1)
ldr r0, [r1, r2, LSL #2]
and r0, r0, #0xff
mov pc, lr
END(a4x_bs_r_1)
ENTRY(a4x_bs_r_2)
ldr r0, [r1, r2, LSL #2]
@ -63,10 +64,12 @@ ENTRY(a4x_bs_r_2)
orr r1, r1, r1, lsl #8
and r0, r0, r1
mov pc, lr
END(a4x_bs_r_2)
ENTRY(a4x_bs_r_4)
ldr r0, [r1, r2, LSL #2]
mov pc, lr
END(a4x_bs_r_4)
/*
* Write single
@ -75,6 +78,7 @@ ENTRY(a4x_bs_w_1)
and r3, r3, #0xff
str r3, [r1, r2, LSL #2]
mov pc, lr
END(a4x_bs_w_1)
ENTRY(a4x_bs_w_2)
mov r0, #0xff
@ -82,10 +86,12 @@ ENTRY(a4x_bs_w_2)
and r3, r3, r0
str r3, [r1, r2, LSL #2]
mov pc, lr
END(a4x_bs_w_2)
ENTRY(a4x_bs_w_4)
str r3, [r1, r2, LSL #2]
mov pc, lr
END(a4x_bs_w_4)
/*
* Read multiple
@ -101,6 +107,7 @@ ENTRY(a4x_bs_rm_1)
strb r3, [r1], #1
bne 1b
mov pc, lr
END(a4x_bs_rm_1)
ENTRY(a4x_bs_rm_2)
add r0, r1, r2, lsl #2
@ -113,6 +120,7 @@ ENTRY(a4x_bs_rm_2)
strh r3, [r1], #2
bne 1b
mov pc, lr
END(a4x_bs_rm_2)
/*
* Write multiple
@ -128,6 +136,7 @@ ENTRY(a4x_bs_wm_1)
str r3, [r0]
bne 1b
mov pc, lr
END(a4x_bs_wm_1)
ENTRY(a4x_bs_wm_2)
add r0, r1, r2, lsl #2
@ -140,3 +149,4 @@ ENTRY(a4x_bs_wm_2)
str r3, [r0]
bne 1b
mov pc, lr
END(a4x_bs_wm_2)

View File

@ -58,6 +58,7 @@ ENTRY(ixp425_pci_mem_bs_r_1)
ldrb r0, [r1, r2]
#endif /* __ARMEB__ */
mov pc, lr
END(ixp425_pci_mem_bs_r_1)
ENTRY(ixp425_pci_mem_bs_r_2)
#ifdef __ARMEB__
@ -68,10 +69,12 @@ ENTRY(ixp425_pci_mem_bs_r_2)
ldrh r0, [r1, r2]
#endif /* __ARMEB__ */
mov pc, lr
END(ixp425_pci_mem_bs_r_2)
ENTRY(ixp425_pci_mem_bs_r_4)
ldr r0, [r1, r2]
mov pc, lr
END(ixp425_pci_mem_bs_r_4)
/*
* write single
@ -86,6 +89,7 @@ ENTRY(ixp425_pci_mem_bs_w_1)
strb r3, [r1, r2]
#endif /* __ARMEB__ */
mov pc, lr
END(ixp425_pci_mem_bs_w_1)
ENTRY(ixp425_pci_mem_bs_w_2)
#ifdef __ARMEB__
@ -96,7 +100,9 @@ ENTRY(ixp425_pci_mem_bs_w_2)
strh r3, [r1, r2]
#endif /* __ARMEB__ */
mov pc, lr
END(ixp425_pci_mem_bs_w_2)
ENTRY(ixp425_pci_mem_bs_w_4)
str r3, [r1, r2]
mov pc, lr
END(ixp425_pci_mem_bs_w_4)

View File

@ -109,6 +109,8 @@ SYSINIT_ENTRY(uniq##_entry, "sysuninit", (subs), \
#define cold 0
#define BUS_PROBE_GENERIC 0
#define CALLOUT_RETURNUNLOCKED 0x1
#undef ffs
#define ffs(x) __builtin_ffs(x)
#undef va_list
#define va_list __builtin_va_list
#undef va_size

View File

@ -433,7 +433,9 @@ static int ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len);
static int ctl_inquiry_evpd(struct ctl_scsiio *ctsio);
static int ctl_inquiry_std(struct ctl_scsiio *ctsio);
static int ctl_get_lba_len(union ctl_io *io, uint64_t *lba, uint64_t *len);
static ctl_action ctl_extent_check(union ctl_io *io1, union ctl_io *io2);
static ctl_action ctl_extent_check(union ctl_io *io1, union ctl_io *io2,
bool seq);
static ctl_action ctl_extent_check_seq(union ctl_io *io1, union ctl_io *io2);
static ctl_action ctl_check_for_blockage(struct ctl_lun *lun,
union ctl_io *pending_io, union ctl_io *ooa_io);
static ctl_action ctl_check_ooa(struct ctl_lun *lun, union ctl_io *pending_io,
@ -4347,8 +4349,7 @@ ctl_init_log_page_index(struct ctl_lun *lun)
continue;
if (page_index->page_code == SLS_LOGICAL_BLOCK_PROVISIONING &&
((lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) == 0 ||
lun->backend->lun_attr == NULL))
lun->backend->lun_attr == NULL)
continue;
if (page_index->page_code != prev) {
@ -4591,6 +4592,17 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
if (value != NULL && strcmp(value, "on") == 0)
lun->flags |= CTL_LUN_READONLY;
lun->serseq = CTL_LUN_SERSEQ_OFF;
if (be_lun->flags & CTL_LUN_FLAG_SERSEQ_READ)
lun->serseq = CTL_LUN_SERSEQ_READ;
value = ctl_get_opt(&be_lun->options, "serseq");
if (value != NULL && strcmp(value, "on") == 0)
lun->serseq = CTL_LUN_SERSEQ_ON;
else if (value != NULL && strcmp(value, "read") == 0)
lun->serseq = CTL_LUN_SERSEQ_READ;
else if (value != NULL && strcmp(value, "off") == 0)
lun->serseq = CTL_LUN_SERSEQ_OFF;
lun->ctl_softc = ctl_softc;
TAILQ_INIT(&lun->ooa_queue);
TAILQ_INIT(&lun->blocked_queue);
@ -10253,8 +10265,8 @@ ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len)
lbp_ptr->page_code = SVPD_LBP;
scsi_ulto2b(sizeof(*lbp_ptr) - 4, lbp_ptr->page_length);
lbp_ptr->threshold_exponent = CTL_LBP_EXPONENT;
if (lun != NULL && lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) {
lbp_ptr->threshold_exponent = CTL_LBP_EXPONENT;
lbp_ptr->flags = SVPD_LBP_UNMAP | SVPD_LBP_WS16 |
SVPD_LBP_WS10 | SVPD_LBP_RZ | SVPD_LBP_ANC_SUP;
lbp_ptr->prov_type = SVPD_LBP_THIN;
@ -10753,15 +10765,15 @@ ctl_get_lba_len(union ctl_io *io, uint64_t *lba, uint64_t *len)
}
static ctl_action
ctl_extent_check_lba(uint64_t lba1, uint64_t len1, uint64_t lba2, uint64_t len2)
ctl_extent_check_lba(uint64_t lba1, uint64_t len1, uint64_t lba2, uint64_t len2,
bool seq)
{
uint64_t endlba1, endlba2;
endlba1 = lba1 + len1 - 1;
endlba1 = lba1 + len1 - (seq ? 0 : 1);
endlba2 = lba2 + len2 - 1;
if ((endlba1 < lba2)
|| (endlba2 < lba1))
if ((endlba1 < lba2) || (endlba2 < lba1))
return (CTL_ACTION_PASS);
else
return (CTL_ACTION_BLOCK);
@ -10800,23 +10812,39 @@ ctl_extent_check_unmap(union ctl_io *io, uint64_t lba2, uint64_t len2)
}
static ctl_action
ctl_extent_check(union ctl_io *io1, union ctl_io *io2)
ctl_extent_check(union ctl_io *io1, union ctl_io *io2, bool seq)
{
uint64_t lba1, lba2;
uint64_t len1, len2;
int retval;
if (ctl_get_lba_len(io1, &lba1, &len1) != 0)
return (CTL_ACTION_ERROR);
retval = ctl_extent_check_unmap(io2, lba1, len1);
if (retval != CTL_ACTION_ERROR)
return (retval);
if (ctl_get_lba_len(io2, &lba2, &len2) != 0)
return (CTL_ACTION_ERROR);
return (ctl_extent_check_lba(lba1, len1, lba2, len2));
retval = ctl_extent_check_unmap(io1, lba2, len2);
if (retval != CTL_ACTION_ERROR)
return (retval);
if (ctl_get_lba_len(io1, &lba1, &len1) != 0)
return (CTL_ACTION_ERROR);
return (ctl_extent_check_lba(lba1, len1, lba2, len2, seq));
}
static ctl_action
ctl_extent_check_seq(union ctl_io *io1, union ctl_io *io2)
{
uint64_t lba1, lba2;
uint64_t len1, len2;
if (ctl_get_lba_len(io1, &lba1, &len1) != 0)
return (CTL_ACTION_ERROR);
if (ctl_get_lba_len(io2, &lba2, &len2) != 0)
return (CTL_ACTION_ERROR);
if (lba1 + len1 == lba2)
return (CTL_ACTION_BLOCK);
return (CTL_ACTION_PASS);
}
static ctl_action
@ -10905,12 +10933,18 @@ ctl_check_for_blockage(struct ctl_lun *lun, union ctl_io *pending_io,
case CTL_SER_BLOCK:
return (CTL_ACTION_BLOCK);
case CTL_SER_EXTENT:
return (ctl_extent_check(pending_io, ooa_io));
return (ctl_extent_check(ooa_io, pending_io,
(lun->serseq == CTL_LUN_SERSEQ_ON)));
case CTL_SER_EXTENTOPT:
if ((lun->mode_pages.control_page[CTL_PAGE_CURRENT].queue_flags
& SCP_QUEUE_ALG_MASK) != SCP_QUEUE_ALG_UNRESTRICTED)
return (ctl_extent_check(pending_io, ooa_io));
/* FALLTHROUGH */
return (ctl_extent_check(ooa_io, pending_io,
(lun->serseq == CTL_LUN_SERSEQ_ON)));
return (CTL_ACTION_PASS);
case CTL_SER_EXTENTSEQ:
if (lun->serseq != CTL_LUN_SERSEQ_OFF)
return (ctl_extent_check_seq(ooa_io, pending_io));
return (CTL_ACTION_PASS);
case CTL_SER_PASS:
return (CTL_ACTION_PASS);
case CTL_SER_BLOCKOPT:
@ -12441,7 +12475,7 @@ ctl_cmd_pattern_match(struct ctl_scsiio *ctsio, struct ctl_error_desc *desc)
return (CTL_LUN_PAT_NONE);
action = ctl_extent_check_lba(lba1, len1, desc->lba_range.lba,
desc->lba_range.len);
desc->lba_range.len, FALSE);
/*
* A "pass" means that the LBA ranges don't overlap, so
* this doesn't match the user's range criteria.
@ -14002,7 +14036,6 @@ ctl_thresh_thread(void *arg)
be_lun = lun->be_lun;
if ((lun->flags & CTL_LUN_DISABLED) ||
(lun->flags & CTL_LUN_OFFLINE) ||
(be_lun->flags & CTL_LUN_FLAG_UNMAP) == 0 ||
lun->backend->lun_attr == NULL)
continue;
rwpage = &lun->mode_pages.rw_er_page[CTL_PAGE_CURRENT];

View File

@ -85,7 +85,8 @@ typedef enum {
CTL_LUN_FLAG_DEVID = 0x20,
CTL_LUN_FLAG_DEV_TYPE = 0x40,
CTL_LUN_FLAG_UNMAP = 0x80,
CTL_LUN_FLAG_OFFLINE = 0x100
CTL_LUN_FLAG_OFFLINE = 0x100,
CTL_LUN_FLAG_SERSEQ_READ = 0x200
} ctl_backend_lun_flags;
#ifdef _KERNEL

View File

@ -2204,6 +2204,8 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_OFFLINE;
if (unmap)
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP;
if (be_lun->dispatch != ctl_be_block_dispatch_dev)
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_SERSEQ_READ;
be_lun->ctl_be_lun.be_lun = be_lun;
be_lun->ctl_be_lun.maxlba = (be_lun->size_blocks == 0) ?
0 : (be_lun->size_blocks - 1);

View File

@ -97,6 +97,7 @@ typedef enum {
CTL_SER_BLOCKOPT,
CTL_SER_EXTENT,
CTL_SER_EXTENTOPT,
CTL_SER_EXTENTSEQ,
CTL_SER_PASS,
CTL_SER_SKIP
} ctl_serialize_action;
@ -182,6 +183,12 @@ typedef enum {
CTL_LUN_READONLY = 0x800
} ctl_lun_flags;
typedef enum {
CTL_LUN_SERSEQ_OFF,
CTL_LUN_SERSEQ_READ,
CTL_LUN_SERSEQ_ON
} ctl_lun_serseq;
typedef enum {
CTLBLOCK_FLAG_NONE = 0x00,
CTLBLOCK_FLAG_INVALID = 0x01
@ -386,6 +393,7 @@ struct ctl_lun {
struct ctl_id target;
uint64_t lun;
ctl_lun_flags flags;
ctl_lun_serseq serseq;
STAILQ_HEAD(,ctl_error_desc) error_list;
uint64_t error_serial;
struct ctl_softc *ctl_softc;

View File

@ -59,12 +59,13 @@
#define bO CTL_SER_BLOCKOPT /* Optional block */
#define xT CTL_SER_EXTENT /* Extent check */
#define xO CTL_SER_EXTENTOPT /* Optional extent check */
#define xS CTL_SER_EXTENTSEQ /* Sequential extent check */
static ctl_serialize_action
ctl_serialize_table[CTL_SERIDX_COUNT][CTL_SERIDX_COUNT] = {
/**>IDX_ :: 2nd:TUR RD WRT UNM MDSN MDSL RQSN INQ RDCP RES LSNS FMT STR*/
/*TUR */{ pS, pS, pS, pS, bK, bK, bK, pS, pS, bK, pS, bK, bK},
/*READ */{ pS, pS, xT, bO, bK, bK, bK, pS, pS, bK, pS, bK, bK},
/*READ */{ pS, xS, xT, bO, bK, bK, bK, pS, pS, bK, pS, bK, bK},
/*WRITE */{ pS, xT, xT, bO, bK, bK, bK, pS, pS, bK, pS, bK, bK},
/*UNMAP */{ pS, xO, xO, pS, bK, bK, bK, pS, pS, bK, pS, bK, bK},
/*MD_SNS */{ bK, bK, bK, bK, pS, bK, bK, pS, pS, bK, pS, bK, bK},

View File

@ -38,11 +38,8 @@ struct cyc_cpu;
typedef struct {
int cpuid;
struct cyc_cpu *cpu_cyclic;
uint32_t cpu_flags;
uint_t cpu_intr_actv;
uintptr_t cpu_profile_pc;
uintptr_t cpu_profile_upc;
uintptr_t cpu_dtrace_caller; /* DTrace: caller, if any */
hrtime_t cpu_dtrace_chillmark; /* DTrace: chill mark time */
hrtime_t cpu_dtrace_chilled; /* DTrace: total chill time */

View File

@ -1,79 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* $FreeBSD$
*
*/
/*
* Copyright (c) 1999-2001 by Sun Microsystems, Inc.
* All rights reserved.
*/
#ifndef _COMPAT_OPENSOLARIS_SYS_CYCLIC_H_
#define _COMPAT_OPENSOLARIS_SYS_CYCLIC_H_
#ifndef _KERNEL
typedef void cpu_t;
#endif
#ifndef _ASM
#include <sys/time.h>
#include <sys/cpuvar.h>
#endif /* !_ASM */
#ifndef _ASM
typedef uintptr_t cyclic_id_t;
typedef int cyc_index_t;
typedef uint16_t cyc_level_t;
typedef void (*cyc_func_t)(void *);
typedef void *cyb_arg_t;
#define CYCLIC_NONE ((cyclic_id_t)0)
typedef struct cyc_handler {
cyc_func_t cyh_func;
void *cyh_arg;
} cyc_handler_t;
typedef struct cyc_time {
hrtime_t cyt_when;
hrtime_t cyt_interval;
} cyc_time_t;
typedef struct cyc_omni_handler {
void (*cyo_online)(void *, cpu_t *, cyc_handler_t *, cyc_time_t *);
void (*cyo_offline)(void *, cpu_t *, void *);
void *cyo_arg;
} cyc_omni_handler_t;
#ifdef _KERNEL
cyclic_id_t cyclic_add(cyc_handler_t *, cyc_time_t *);
cyclic_id_t cyclic_add_omni(cyc_omni_handler_t *);
void cyclic_remove(cyclic_id_t);
#endif /* _KERNEL */
#endif /* !_ASM */
#endif

View File

@ -1,311 +0,0 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* $FreeBSD$
*
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _COMPAT_OPENSOLARIS_SYS_CYCLIC_IMPL_H_
#define _COMPAT_OPENSOLARIS_SYS_CYCLIC_IMPL_H_
#include <sys/cyclic.h>
/*
* Cyclic Subsystem Backend-supplied Interfaces
* --------------------------------------------
*
* 0 Background
*
* The design, implementation and interfaces of the cyclic subsystem are
* covered in detail in block comments in the implementation. This
* comment covers the interface from the cyclic subsystem into the cyclic
* backend. The backend is specified by a structure of function pointers
* defined below.
*
* 1 Overview
*
* cyb_configure() <-- Configures the backend on the specified CPU
* cyb_unconfigure() <-- Unconfigures the backend
* cyb_enable() <-- Enables the CY_HIGH_LEVEL interrupt source
* cyb_disable() <-- Disables the CY_HIGH_LEVEL interrupt source
* cyb_reprogram() <-- Reprograms the CY_HIGH_LEVEL interrupt source
* cyb_xcall() <-- Cross calls to the specified CPU
*
* 2 cyb_arg_t cyb_configure(cpu_t *)
*
* 2.1 Overview
*
* cyb_configure() should configure the specified CPU for cyclic operation.
*
* 2.2 Arguments and notes
*
* cyb_configure() should initialize any backend-specific per-CPU
* structures for the specified CPU. cyb_configure() will be called for
* each CPU (including the boot CPU) during boot. If the platform
* supports dynamic reconfiguration, cyb_configure() will be called for
* new CPUs as they are configured into the system.
*
* 2.3 Return value
*
* cyb_configure() is expected to return a cookie (a cyb_arg_t, which is
* of type void *) which will be used as the first argument for all future
* cyclic calls into the backend on the specified CPU.
*
* 2.4 Caller's context
*
* cpu_lock will be held. The caller's CPU is unspecified, and may or
* may not be the CPU specified to cyb_configure().
*
* 3 void cyb_unconfigure(cyb_arg_t arg)
*
* 3.1 Overview
*
* cyb_unconfigure() should unconfigure the specified backend.
*
* 3.2 Arguments and notes
*
* The only argument to cyb_unconfigure() is a cookie as returned from
* cyb_configure().
*
* cyb_unconfigure() should free any backend-specific per-CPU structures
* for the specified backend. cyb_unconfigure() will _only_ be called on
* platforms which support dynamic reconfiguration. If the platform does
* not support dynamic reconfiguration, cyb_unconfigure() may panic.
*
* After cyb_unconfigure() returns, the backend must not call cyclic_fire()
* on the corresponding CPU; doing so will result in a bad trap.
*
* 3.3 Return value
*
* None.
*
* 3.4 Caller's context
*
* cpu_lock will be held. The caller's CPU is unspecified, and may or
* may not be the CPU specified to cyb_unconfigure(). The specified
* CPU is guaranteed to exist at the time cyb_unconfigure() is called.
* The cyclic subsystem is guaranteed to be suspended when cyb_unconfigure()
* is called, and interrupts are guaranteed to be disabled.
*
* 4 void cyb_enable(cyb_arg_t arg)
*
* 4.1 Overview
*
* cyb_enable() should enable the CY_HIGH_LEVEL interrupt source on
* the specified backend.
*
* 4.2 Arguments and notes
*
* The only argument to cyb_enable() is a backend cookie as returned from
* cyb_configure().
*
* cyb_enable() will only be called if a) the specified backend has never
* been enabled or b) the specified backend has been explicitly disabled with
* cyb_disable(). In either case, cyb_enable() will only be called if
* the cyclic subsystem wishes to add a cyclic to the CPU corresponding
* to the specified backend. cyb_enable() will be called before
* cyb_reprogram() for a given backend.
*
* cyclic_fire() should not be called on a CPU which has not had its backend
* explicitly cyb_enable()'d, but to do so does not constitute fatal error.
*
* 4.3 Return value
*
* None.
*
* 4.4 Caller's context
*
* cyb_enable() will only be called from CY_HIGH_LEVEL context on the CPU
* corresponding to the specified backend.
*
* 5 void cyb_disable(cyb_arg_t arg)
*
* 5.1 Overview
*
* cyb_disable() should disable the CY_HIGH_LEVEL interrupt source on
* the specified backend.
*
* 5.2 Arguments and notes
*
* The only argument to cyb_disable() is a backend cookie as returned from
* cyb_configure().
*
* cyb_disable() will only be called on backends which have been previously
* been cyb_enable()'d. cyb_disable() will be called when all cyclics have
* been juggled away or removed from a cyb_enable()'d CPU.
*
* cyclic_fire() should not be called on a CPU which has had its backend
* explicitly cyb_disable()'d, but to do so does not constitute fatal
* error. cyb_disable() is thus not required to check for a pending
* CY_HIGH_LEVEL interrupt.
*
* 5.3 Return value
*
* None.
*
* 5.4 Caller's context
*
* cyb_disable() will only be called from CY_HIGH_LEVEL context on the CPU
* corresponding to the specified backend.
*
* 6 void cyb_reprogram(cyb_arg_t arg, hrtime_t time)
*
* 6.1 Overview
*
* cyb_reprogram() should reprogram the CY_HIGH_LEVEL interrupt source
* to fire at the absolute time specified.
*
* 6.2 Arguments and notes
*
* The first argument to cyb_reprogram() is a backend cookie as returned from
* cyb_configure().
*
* The second argument is an absolute time at which the CY_HIGH_LEVEL
* interrupt should fire. The specified time _may_ be in the past (albeit
* the very recent past). If this is the case, the backend should generate
* a CY_HIGH_LEVEL interrupt as soon as possible.
*
* The platform should not assume that cyb_reprogram() will be called with
* monotonically increasing values.
*
* If the platform does not allow for interrupts at arbitrary times in the
* future, cyb_reprogram() may do nothing -- as long as cyclic_fire() is
* called periodically at CY_HIGH_LEVEL. While this is clearly suboptimal
* (cyclic granularity will be bounded by the length of the period between
* cyclic_fire()'s), it allows the cyclic subsystem to be implemented on
* inferior hardware.
*
* 6.3 Return value
*
* None.
*
* 6.4 Caller's context
*
* cyb_reprogram() will only be called from CY_HIGH_LEVEL context on the CPU
* corresponding to the specified backend.
*
* 10 cyb_xcall(cyb_arg_t arg, cpu_t *, void(*func)(void *), void *farg)
*
* 10.1 Overview
*
* cyb_xcall() should execute the specified function on the specified CPU.
*
* 10.2 Arguments and notes
*
* The first argument to cyb_restore_level() is a backend cookie as returned
* from cyb_configure(). The second argument is a CPU on which the third
* argument, a function pointer, should be executed. The fourth argument,
* a void *, should be passed as the argument to the specified function.
*
* cyb_xcall() must provide exactly-once semantics. If the specified
* function is called more than once, or not at all, the cyclic subsystem
* will become internally inconsistent. The specified function must be
* be executed on the specified CPU, but may be executed in any context
* (any interrupt context or kernel context).
*
* cyb_xcall() cannot block. Any resources which cyb_xcall() needs to
* acquire must thus be protected by synchronization primitives which
* never require the caller to block.
*
* 10.3 Return value
*
* None.
*
* 10.4 Caller's context
*
* cpu_lock will be held and kernel preemption may be disabled. The caller
* may be unable to block, giving rise to the constraint outlined in
* 10.2, above.
*
*/
typedef struct cyc_backend {
cyb_arg_t (*cyb_configure)(cpu_t *);
void (*cyb_unconfigure)(cyb_arg_t);
void (*cyb_enable)(cyb_arg_t);
void (*cyb_disable)(cyb_arg_t);
void (*cyb_reprogram)(cyb_arg_t, hrtime_t);
void (*cyb_xcall)(cyb_arg_t, cpu_t *, cyc_func_t, void *);
cyb_arg_t cyb_arg;
} cyc_backend_t;
#define CYF_FREE 0x0001
typedef struct cyclic {
hrtime_t cy_expire;
hrtime_t cy_interval;
void (*cy_handler)(void *);
void *cy_arg;
uint16_t cy_flags;
} cyclic_t;
typedef struct cyc_cpu {
cpu_t *cyp_cpu;
cyc_index_t *cyp_heap;
cyclic_t *cyp_cyclics;
cyc_index_t cyp_nelems;
cyc_index_t cyp_size;
cyc_backend_t *cyp_backend;
struct mtx cyp_mtx;
} cyc_cpu_t;
typedef struct cyc_omni_cpu {
cyc_cpu_t *cyo_cpu;
cyc_index_t cyo_ndx;
void *cyo_arg;
struct cyc_omni_cpu *cyo_next;
} cyc_omni_cpu_t;
typedef struct cyc_id {
cyc_cpu_t *cyi_cpu;
cyc_index_t cyi_ndx;
struct cyc_id *cyi_prev;
struct cyc_id *cyi_next;
cyc_omni_handler_t cyi_omni_hdlr;
cyc_omni_cpu_t *cyi_omni_list;
} cyc_id_t;
typedef struct cyc_xcallarg {
cyc_cpu_t *cyx_cpu;
cyc_handler_t *cyx_hdlr;
cyc_time_t *cyx_when;
cyc_index_t cyx_ndx;
cyc_index_t *cyx_heap;
cyclic_t *cyx_cyclics;
cyc_index_t cyx_size;
uint16_t cyx_flags;
int cyx_wait;
} cyc_xcallarg_t;
#define CY_DEFAULT_PERCPU 1
#define CY_PASSIVE_LEVEL -1
#define CY_WAIT 0
#define CY_NOWAIT 1
#define CYC_HEAP_PARENT(ndx) (((ndx) - 1) >> 1)
#define CYC_HEAP_RIGHT(ndx) (((ndx) + 1) << 1)
#define CYC_HEAP_LEFT(ndx) ((((ndx) + 1) << 1) - 1)
#endif

View File

@ -176,7 +176,7 @@ dtrace_optval_t dtrace_ustackframes_default = 20;
dtrace_optval_t dtrace_jstackframes_default = 50;
dtrace_optval_t dtrace_jstackstrsize_default = 512;
int dtrace_msgdsize_max = 128;
hrtime_t dtrace_chill_max = 500 * (NANOSEC / MILLISEC); /* 500 ms */
hrtime_t dtrace_chill_max = MSEC2NSEC(500); /* 500 ms */
hrtime_t dtrace_chill_interval = NANOSEC; /* 1000 ms */
int dtrace_devdepth_max = 32;
int dtrace_err_verbose;
@ -13782,7 +13782,7 @@ dtrace_dof_slurp(dof_hdr_t *dof, dtrace_vstate_t *vstate, cred_t *cr,
if (!(sec->dofs_flags & DOF_SECF_LOAD))
continue; /* just ignore non-loadable sections */
if (sec->dofs_align & (sec->dofs_align - 1)) {
if (!ISP2(sec->dofs_align)) {
dtrace_dof_error(dof, "bad section alignment");
return (-1);
}
@ -17947,6 +17947,5 @@ SYSINIT(dtrace_anon_init, SI_SUB_DTRACE_ANON, SI_ORDER_FIRST, dtrace_anon_init,
DEV_MODULE(dtrace, dtrace_modevent, NULL);
MODULE_VERSION(dtrace, 1);
MODULE_DEPEND(dtrace, cyclic, 1, 1, 1);
MODULE_DEPEND(dtrace, opensolaris, 1, 1, 1);
#endif

View File

@ -2483,7 +2483,7 @@ fasttrap_load(void)
if (nent == 0 || nent > 0x1000000)
nent = FASTTRAP_TPOINTS_DEFAULT_SIZE;
if ((nent & (nent - 1)) == 0)
if (ISP2(nent))
fasttrap_tpoints.fth_nent = nent;
else
fasttrap_tpoints.fth_nent = 1 << fasttrap_highbit(nent);
@ -2501,7 +2501,7 @@ fasttrap_load(void)
* ... and the providers hash table...
*/
nent = FASTTRAP_PROVIDERS_DEFAULT_SIZE;
if ((nent & (nent - 1)) == 0)
if (ISP2(nent))
fasttrap_provs.fth_nent = nent;
else
fasttrap_provs.fth_nent = 1 << fasttrap_highbit(nent);
@ -2537,7 +2537,7 @@ fasttrap_load(void)
* ... and the procs hash table.
*/
nent = FASTTRAP_PROCS_DEFAULT_SIZE;
if ((nent & (nent - 1)) == 0)
if (ISP2(nent))
fasttrap_procs.fth_nent = nent;
else
fasttrap_procs.fth_nent = 1 << fasttrap_highbit(nent);

View File

@ -409,11 +409,11 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
offsetof(dmu_sendarg_t, dsa_link));
if (doi.doi_type == DMU_OTN_ZAP_METADATA) {
err = zap_contains(mos, dsobj, DS_FIELD_LARGE_BLOCKS);
if (err == 0)
int zaperr = zap_contains(mos, dsobj, DS_FIELD_LARGE_BLOCKS);
if (zaperr != ENOENT) {
VERIFY0(zaperr);
ds->ds_large_blocks = B_TRUE;
else
ASSERT3U(err, ==, ENOENT);
}
}
if (err == 0) {

View File

@ -1483,7 +1483,7 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
}
if (scn->scn_visited_this_txg) {
zfs_dbgmsg("freed %llu blocks in %llums from "
"free_bpobj/bptree txg %llu; err=%u",
"free_bpobj/bptree txg %llu; err=%d",
(longlong_t)scn->scn_visited_this_txg,
(longlong_t)
NSEC2MSEC(gethrtime() - scn->scn_sync_start_time),

View File

@ -24,6 +24,7 @@
* Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/sysmacros.h>
#include <sys/zfs_context.h>
#include <sys/fm/fs/zfs.h>
#include <sys/spa.h>
@ -151,7 +152,7 @@ zio_init(void)
size_t align = 0;
size_t cflags = (size > zio_buf_debug_limit) ? KMC_NODEBUG : 0;
while (p2 & (p2 - 1))
while (!ISP2(p2))
p2 &= p2 - 1;
#ifdef illumos

View File

@ -21,6 +21,7 @@
/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2014 Igor Kozhukhov <ikozhukhov@gmail.com>.
*/
#ifndef _SYS_CPUVAR_H
@ -31,6 +32,7 @@
#include <sys/disp.h>
#include <sys/processor.h>
#include <sys/loadavg.h>
#if (defined(_KERNEL) || defined(_KMEMUSER)) && defined(_MACHDEP)
#include <sys/machcpuvar.h>
#endif
@ -52,15 +54,6 @@ extern "C" {
struct squeue_set_s;
#define CPU_CACHE_COHERENCE_SIZE 64
#define S_LOADAVG_SZ 11
#define S_MOVAVG_SZ 10
struct loadavg_s {
int lg_cur; /* current loadavg entry */
unsigned int lg_len; /* number entries recorded */
hrtime_t lg_total; /* used to temporarily hold load totals */
hrtime_t lg_loads[S_LOADAVG_SZ]; /* table of recorded entries */
};
/*
* For fast event tracing.
@ -655,7 +648,7 @@ void poke_cpu(int cpun); /* interrupt another CPU (to preempt) */
void mach_cpu_pause(volatile char *);
void pause_cpus(cpu_t *off_cp);
void pause_cpus(cpu_t *off_cp, void *(*func)(void *));
void start_cpus(void);
int cpus_paused(void);

View File

@ -57,6 +57,7 @@ extern "C" {
#if defined(sun)
#include <sys/systm.h>
#else
#include <sys/cpuvar.h>
#include <sys/param.h>
#include <sys/linker.h>
#include <sys/ioccom.h>
@ -64,8 +65,8 @@ extern "C" {
typedef int model_t;
#endif
#include <sys/ctf_api.h>
#include <sys/cyclic.h>
#if defined(sun)
#include <sys/cyclic.h>
#include <sys/int_limits.h>
#else
#include <sys/stdint.h>

View File

@ -377,7 +377,9 @@ extern "C" {
/*
* Define the appropriate "implementation choices".
*/
#if !defined(_ILP32)
#define _ILP32
#endif
#if !defined(_I32LPx) && defined(_KERNEL)
#define _I32LPx
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,301 +0,0 @@
/*-
* Copyright 2007 John Birrell <jb@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*
*/
#include <sys/cdefs.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/conf.h>
#include <sys/kthread.h>
#include <sys/module.h>
#include <sys/sysctl.h>
#include <sys/cyclic.h>
#include <sys/time.h>
static struct timespec test_001_start;
static void
cyclic_test_001_func(void *arg)
{
struct timespec ts;
nanotime(&ts);
timespecsub(&ts,&test_001_start);
printf("%s: called after %lu.%09lu on curcpu %d\n",__func__,(u_long) ts.tv_sec,(u_long) ts.tv_nsec, curcpu);
}
static void
cyclic_test_001(void)
{
int error = 0;
cyc_handler_t hdlr;
cyc_time_t when;
cyclic_id_t id;
printf("%s: starting\n",__func__);
hdlr.cyh_func = (cyc_func_t) cyclic_test_001_func;
hdlr.cyh_arg = 0;
when.cyt_when = 0;
when.cyt_interval = 1000000000;
nanotime(&test_001_start);
mutex_enter(&cpu_lock);
id = cyclic_add(&hdlr, &when);
mutex_exit(&cpu_lock);
DELAY(1200000);
mutex_enter(&cpu_lock);
cyclic_remove(id);
mutex_exit(&cpu_lock);
printf("%s: %s\n",__func__, error == 0 ? "passed":"failed");
}
static struct timespec test_002_start;
static void
cyclic_test_002_func(void *arg)
{
struct timespec ts;
nanotime(&ts);
timespecsub(&ts,&test_002_start);
printf("%s: called after %lu.%09lu on curcpu %d\n",__func__,(u_long) ts.tv_sec,(u_long) ts.tv_nsec, curcpu);
}
static void
cyclic_test_002_online(void *arg, cpu_t *c, cyc_handler_t *hdlr, cyc_time_t *t)
{
printf("%s: online on curcpu %d\n",__func__, curcpu);
hdlr->cyh_func = cyclic_test_002_func;
hdlr->cyh_arg = NULL;
t->cyt_when = 0;
t->cyt_interval = 1000000000;
}
static void
cyclic_test_002_offline(void *arg, cpu_t *c, void *arg1)
{
printf("%s: offline on curcpu %d\n",__func__, curcpu);
}
static void
cyclic_test_002(void)
{
int error = 0;
cyc_omni_handler_t hdlr;
cyclic_id_t id;
printf("%s: starting\n",__func__);
hdlr.cyo_online = cyclic_test_002_online;
hdlr.cyo_offline = cyclic_test_002_offline;
hdlr.cyo_arg = NULL;
nanotime(&test_002_start);
mutex_enter(&cpu_lock);
id = cyclic_add_omni(&hdlr);
mutex_exit(&cpu_lock);
DELAY(1200000);
mutex_enter(&cpu_lock);
cyclic_remove(id);
mutex_exit(&cpu_lock);
printf("%s: %s\n",__func__, error == 0 ? "passed":"failed");
}
static struct timespec test_003_start;
static void
cyclic_test_003_func(void *arg)
{
struct timespec ts;
nanotime(&ts);
timespecsub(&ts,&test_003_start);
printf("%s: called after %lu.%09lu on curcpu %d id %ju\n",__func__,(u_long) ts.tv_sec,(u_long) ts.tv_nsec, curcpu, (uintmax_t)(uintptr_t) arg);
}
static void
cyclic_test_003(void)
{
int error = 0;
cyc_handler_t hdlr;
cyc_time_t when;
cyclic_id_t id;
cyclic_id_t id1;
cyclic_id_t id2;
cyclic_id_t id3;
printf("%s: starting\n",__func__);
hdlr.cyh_func = (cyc_func_t) cyclic_test_003_func;
when.cyt_when = 0;
nanotime(&test_003_start);
mutex_enter(&cpu_lock);
when.cyt_interval = 200000000;
hdlr.cyh_arg = (void *) 0UL;
id = cyclic_add(&hdlr, &when);
when.cyt_interval = 400000000;
hdlr.cyh_arg = (void *) 1UL;
id1 = cyclic_add(&hdlr, &when);
hdlr.cyh_arg = (void *) 2UL;
when.cyt_interval = 1000000000;
id2 = cyclic_add(&hdlr, &when);
hdlr.cyh_arg = (void *) 3UL;
when.cyt_interval = 1300000000;
id3 = cyclic_add(&hdlr, &when);
mutex_exit(&cpu_lock);
DELAY(1200000);
mutex_enter(&cpu_lock);
cyclic_remove(id);
cyclic_remove(id1);
cyclic_remove(id2);
cyclic_remove(id3);
mutex_exit(&cpu_lock);
printf("%s: %s\n",__func__, error == 0 ? "passed":"failed");
}
/* Kernel thread command routine. */
static void
cyclic_run_tests(void *arg)
{
intptr_t cmd = (intptr_t) arg;
switch (cmd) {
case 1:
cyclic_test_001();
break;
case 2:
cyclic_test_002();
break;
case 3:
cyclic_test_003();
break;
default:
cyclic_test_001();
cyclic_test_002();
cyclic_test_003();
break;
}
printf("%s: finished\n",__func__);
kthread_exit();
}
static int
cyclic_test(SYSCTL_HANDLER_ARGS)
{
int error, cmd = 0;
error = sysctl_wire_old_buffer(req, sizeof(int));
if (error == 0)
error = sysctl_handle_int(oidp, &cmd, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
/* Check for command validity. */
switch (cmd) {
case 1:
case 2:
case -1:
/*
* Execute the tests in a kernel thread to avoid blocking
* the sysctl. Look for the results in the syslog.
*/
error = kthread_add(cyclic_run_tests, (void *)(uintptr_t) cmd,
NULL, NULL, 0, 0, "cyctest%d", cmd);
break;
default:
printf("Usage: debug.cyclic.test=(1..9) or -1 for all tests\n");
error = EINVAL;
break;
}
return (error);
}
SYSCTL_NODE(_debug, OID_AUTO, cyclic, CTLFLAG_RW, NULL, "Cyclic nodes");
SYSCTL_PROC(_debug_cyclic, OID_AUTO, test, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
cyclic_test, "I", "Enables a cyclic test. Use -1 for all tests.");
static int
cyclic_test_modevent(module_t mod, int type, void *data)
{
int error = 0;
switch (type) {
case MOD_LOAD:
break;
case MOD_UNLOAD:
break;
case MOD_SHUTDOWN:
break;
default:
error = EOPNOTSUPP;
break;
}
return (error);
}
DEV_MODULE(cyclic_test, cyclic_test_modevent, NULL);
MODULE_VERSION(cyclic_test, 1);
MODULE_DEPEND(cyclic_test, cyclic, 1, 1, 1);
MODULE_DEPEND(cyclic_test, opensolaris, 1, 1, 1);

View File

@ -1,131 +0,0 @@
/*-
* Copyright 2006-2008 John Birrell <jb@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*
*/
static void enable(cyb_arg_t);
static void disable(cyb_arg_t);
static void reprogram(cyb_arg_t, hrtime_t);
static void xcall(cyb_arg_t, cpu_t *, cyc_func_t, void *);
static void cyclic_clock(struct trapframe *frame);
static cyc_backend_t be = {
NULL, /* cyb_configure */
NULL, /* cyb_unconfigure */
enable,
disable,
reprogram,
xcall,
NULL /* cyb_arg_t cyb_arg */
};
static void
cyclic_ap_start(void *dummy)
{
/* Initialise the rest of the CPUs. */
cyclic_clock_func = cyclic_clock;
cyclic_mp_init();
}
SYSINIT(cyclic_ap_start, SI_SUB_SMP, SI_ORDER_ANY, cyclic_ap_start, NULL);
/*
* Machine dependent cyclic subsystem initialisation.
*/
static void
cyclic_machdep_init(void)
{
/* Register the cyclic backend. */
cyclic_init(&be);
}
static void
cyclic_machdep_uninit(void)
{
/* De-register the cyclic backend. */
cyclic_uninit();
}
/*
* This function is the one registered by the machine dependent
* initialiser as the callback for high speed timer events.
*/
static void
cyclic_clock(struct trapframe *frame)
{
cpu_t *c = &solaris_cpu[curcpu];
if (c->cpu_cyclic != NULL) {
if (TRAPF_USERMODE(frame)) {
c->cpu_profile_pc = 0;
c->cpu_profile_upc = TRAPF_PC(frame);
} else {
c->cpu_profile_pc = TRAPF_PC(frame);
c->cpu_profile_upc = 0;
}
c->cpu_intr_actv = 1;
/* Fire any timers that are due. */
cyclic_fire(c);
c->cpu_intr_actv = 0;
}
}
static void
enable(cyb_arg_t arg __unused)
{
}
static void
disable(cyb_arg_t arg __unused)
{
}
static void
reprogram(cyb_arg_t arg __unused, hrtime_t exp)
{
struct bintime bt;
struct timespec ts;
ts.tv_sec = exp / 1000000000;
ts.tv_nsec = exp % 1000000000;
timespec2bintime(&ts, &bt);
clocksource_cyc_set(&bt);
}
static void xcall(cyb_arg_t arg __unused, cpu_t *c, cyc_func_t func,
void *param)
{
cpuset_t cpus;
CPU_SETOF(c->cpuid, &cpus);
smp_rendezvous_cpus(cpus,
smp_no_rendevous_barrier, func, smp_no_rendevous_barrier, param);
}

View File

@ -144,13 +144,6 @@ fbt_provide_module(void *arg, modctl_t *lf)
if (strcmp(modname, "dtrace") == 0)
return;
/*
* The cyclic timer subsystem can be built as a module and DTrace
* depends on that, so it is ineligible too.
*/
if (strcmp(modname, "cyclic") == 0)
return;
/*
* To register with DTrace, a module must list 'dtrace' as a
* dependency in order for the kernel linker to resolve

View File

@ -52,9 +52,9 @@
#include <sys/smp.h>
#include <sys/uio.h>
#include <sys/unistd.h>
#include <machine/cpu.h>
#include <machine/stdarg.h>
#include <sys/cyclic.h>
#include <sys/dtrace.h>
#include <sys/dtrace_bsd.h>
@ -97,7 +97,7 @@
* allow for a manual override in case we get it completely wrong.
*/
#ifdef __amd64
#define PROF_ARTIFICIAL_FRAMES 7
#define PROF_ARTIFICIAL_FRAMES 10
#else
#ifdef __i386
#define PROF_ARTIFICIAL_FRAMES 6
@ -126,18 +126,30 @@
#define PROF_ARTIFICIAL_FRAMES 3
#endif
struct profile_probe_percpu;
typedef struct profile_probe {
char prof_name[PROF_NAMELEN];
dtrace_id_t prof_id;
int prof_kind;
#ifdef illumos
hrtime_t prof_interval;
cyclic_id_t prof_cyclic;
#else
sbintime_t prof_interval;
struct callout prof_cyclic;
sbintime_t prof_expected;
struct profile_probe_percpu **prof_pcpus;
#endif
} profile_probe_t;
typedef struct profile_probe_percpu {
hrtime_t profc_expected;
hrtime_t profc_interval;
profile_probe_t *profc_probe;
#ifdef __FreeBSD__
struct callout profc_cyclic;
#endif
} profile_probe_percpu_t;
static d_open_t profile_open;
@ -206,29 +218,92 @@ static dtrace_provider_id_t profile_id;
static hrtime_t profile_interval_min = NANOSEC / 5000; /* 5000 hz */
static int profile_aframes = 0; /* override */
static sbintime_t
nsec_to_sbt(hrtime_t nsec)
{
time_t sec;
/*
* We need to calculate nsec * 2^32 / 10^9
* Seconds and nanoseconds are split to avoid overflow.
*/
sec = nsec / NANOSEC;
nsec = nsec % NANOSEC;
return (((sbintime_t)sec << 32) | ((sbintime_t)nsec << 32) / NANOSEC);
}
static hrtime_t
sbt_to_nsec(sbintime_t sbt)
{
return ((sbt >> 32) * NANOSEC +
(((uint32_t)sbt * (hrtime_t)NANOSEC) >> 32));
}
static void
profile_fire(void *arg)
{
profile_probe_percpu_t *pcpu = arg;
profile_probe_t *prof = pcpu->profc_probe;
hrtime_t late;
solaris_cpu_t *c = &solaris_cpu[curcpu];
struct trapframe *frame;
uintfptr_t pc, upc;
#ifdef illumos
late = gethrtime() - pcpu->profc_expected;
pcpu->profc_expected += pcpu->profc_interval;
#else
late = sbt_to_nsec(sbinuptime() - pcpu->profc_expected);
#endif
dtrace_probe(prof->prof_id, c->cpu_profile_pc,
c->cpu_profile_upc, late, 0, 0);
pc = 0;
upc = 0;
/*
* td_intr_frame can be unset if this is a catch up event
* after waking up from idle sleep.
* This can only happen on a CPU idle thread.
*/
frame = curthread->td_intr_frame;
if (frame != NULL) {
if (TRAPF_USERMODE(frame))
upc = TRAPF_PC(frame);
else
pc = TRAPF_PC(frame);
}
dtrace_probe(prof->prof_id, pc, upc, late, 0, 0);
pcpu->profc_expected += pcpu->profc_interval;
callout_schedule_sbt_curcpu(&pcpu->profc_cyclic,
pcpu->profc_expected, 0, C_DIRECT_EXEC | C_ABSOLUTE);
}
static void
profile_tick(void *arg)
{
profile_probe_t *prof = arg;
solaris_cpu_t *c = &solaris_cpu[curcpu];
struct trapframe *frame;
uintfptr_t pc, upc;
dtrace_probe(prof->prof_id, c->cpu_profile_pc,
c->cpu_profile_upc, 0, 0, 0);
pc = 0;
upc = 0;
/*
* td_intr_frame can be unset if this is a catch up event
* after waking up from idle sleep.
* This can only happen on a CPU idle thread.
*/
frame = curthread->td_intr_frame;
if (frame != NULL) {
if (TRAPF_USERMODE(frame))
upc = TRAPF_PC(frame);
else
pc = TRAPF_PC(frame);
}
dtrace_probe(prof->prof_id, pc, upc, 0, 0, 0);
prof->prof_expected += prof->prof_interval;
callout_schedule_sbt(&prof->prof_cyclic,
prof->prof_expected, 0, C_DIRECT_EXEC | C_ABSOLUTE);
}
static void
@ -250,8 +325,13 @@ profile_create(hrtime_t interval, char *name, int kind)
prof = kmem_zalloc(sizeof (profile_probe_t), KM_SLEEP);
(void) strcpy(prof->prof_name, name);
#ifdef illumos
prof->prof_interval = interval;
prof->prof_cyclic = CYCLIC_NONE;
#else
prof->prof_interval = nsec_to_sbt(interval);
callout_init(&prof->prof_cyclic, CALLOUT_MPSAFE);
#endif
prof->prof_kind = kind;
prof->prof_id = dtrace_probe_create(profile_id,
NULL, NULL, name,
@ -396,13 +476,18 @@ profile_destroy(void *arg, dtrace_id_t id, void *parg)
{
profile_probe_t *prof = parg;
#ifdef illumos
ASSERT(prof->prof_cyclic == CYCLIC_NONE);
#else
ASSERT(!callout_active(&prof->prof_cyclic) && prof->prof_pcpus == NULL);
#endif
kmem_free(prof, sizeof (profile_probe_t));
ASSERT(profile_total >= 1);
atomic_add_32(&profile_total, -1);
}
#ifdef illumos
/*ARGSUSED*/
static void
profile_online(void *arg, cpu_t *cpu, cyc_handler_t *hdlr, cyc_time_t *when)
@ -478,6 +563,81 @@ profile_disable(void *arg, dtrace_id_t id, void *parg)
prof->prof_cyclic = CYCLIC_NONE;
}
#else
static void
profile_enable_omni(profile_probe_t *prof)
{
profile_probe_percpu_t *pcpu;
int cpu;
prof->prof_pcpus = kmem_zalloc((mp_maxid + 1) * sizeof(pcpu), KM_SLEEP);
CPU_FOREACH(cpu) {
pcpu = kmem_zalloc(sizeof(profile_probe_percpu_t), KM_SLEEP);
prof->prof_pcpus[cpu] = pcpu;
pcpu->profc_probe = prof;
pcpu->profc_expected = sbinuptime() + prof->prof_interval;
pcpu->profc_interval = prof->prof_interval;
callout_init(&pcpu->profc_cyclic, CALLOUT_MPSAFE);
callout_reset_sbt_on(&pcpu->profc_cyclic,
pcpu->profc_expected, 0, profile_fire, pcpu,
cpu, C_DIRECT_EXEC | C_ABSOLUTE);
}
}
static void
profile_disable_omni(profile_probe_t *prof)
{
profile_probe_percpu_t *pcpu;
int cpu;
ASSERT(prof->prof_pcpus != NULL);
CPU_FOREACH(cpu) {
pcpu = prof->prof_pcpus[cpu];
ASSERT(pcpu->profc_probe == prof);
ASSERT(callout_active(&pcpu->profc_cyclic));
callout_stop(&pcpu->profc_cyclic);
callout_drain(&pcpu->profc_cyclic);
kmem_free(pcpu, sizeof(profile_probe_percpu_t));
}
kmem_free(prof->prof_pcpus, (mp_maxid + 1) * sizeof(pcpu));
prof->prof_pcpus = NULL;
}
/* ARGSUSED */
static void
profile_enable(void *arg, dtrace_id_t id, void *parg)
{
profile_probe_t *prof = parg;
if (prof->prof_kind == PROF_TICK) {
prof->prof_expected = sbinuptime() + prof->prof_interval;
callout_reset_sbt(&prof->prof_cyclic,
prof->prof_expected, 0, profile_tick, prof,
C_DIRECT_EXEC | C_ABSOLUTE);
} else {
ASSERT(prof->prof_kind == PROF_PROFILE);
profile_enable_omni(prof);
}
}
/* ARGSUSED */
static void
profile_disable(void *arg, dtrace_id_t id, void *parg)
{
profile_probe_t *prof = parg;
if (prof->prof_kind == PROF_TICK) {
ASSERT(callout_active(&prof->prof_cyclic));
callout_stop(&prof->prof_cyclic);
callout_drain(&prof->prof_cyclic);
} else {
ASSERT(prof->prof_kind == PROF_PROFILE);
profile_disable_omni(prof);
}
}
#endif
static void
profile_load(void *dummy)
{
@ -541,5 +701,4 @@ SYSUNINIT(profile_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, profile_unload,
DEV_MODULE(profile, profile_modevent, NULL);
MODULE_VERSION(profile, 1);
MODULE_DEPEND(profile, dtrace, 1, 1, 1);
MODULE_DEPEND(profile, cyclic, 1, 1, 1);
MODULE_DEPEND(profile, opensolaris, 1, 1, 1);

View File

@ -695,6 +695,7 @@ struct sge {
struct sge_iq **iqmap; /* iq->cntxt_id to iq mapping */
struct sge_eq **eqmap; /* eq->cntxt_id to eq mapping */
int pad_boundary;
int pack_boundary;
int8_t safe_hwidx1; /* may not have room for metadata */
int8_t safe_hwidx2; /* with room for metadata and maybe more */

View File

@ -120,19 +120,10 @@ TUNABLE_INT("hw.cxgbe.buffer_packing", &buffer_packing);
/*
* Start next frame in a packed buffer at this boundary.
* -1: driver should figure out a good value.
* T4:
* ---
* if fl_pad != 0
* value specified here will be overridden by fl_pad.
* else
* power of 2 from 32 to 4096 (both inclusive) is a valid value here.
* T5:
* ---
* 16, or a power of 2 from 64 to 4096 (both inclusive) is a valid value.
* T4: driver will ignore this and use the same value as fl_pad above.
* T5: 16, or a power of 2 from 64 to 4096 (both inclusive) is a valid value.
*/
static int fl_pack = -1;
static int t4_fl_pack;
static int t5_fl_pack;
TUNABLE_INT("hw.cxgbe.fl_pack", &fl_pack);
/*
@ -175,8 +166,7 @@ static int service_iq(struct sge_iq *, int);
static struct mbuf *get_fl_payload(struct adapter *, struct sge_fl *, uint32_t);
static int t4_eth_rx(struct sge_iq *, const struct rss_header *, struct mbuf *);
static inline void init_iq(struct sge_iq *, struct adapter *, int, int, int);
static inline void init_fl(struct adapter *, struct sge_fl *, int, int, int,
char *);
static inline void init_fl(struct adapter *, struct sge_fl *, int, int, char *);
static inline void init_eq(struct sge_eq *, int, int, uint8_t, uint16_t,
char *);
static int alloc_ring(struct adapter *, size_t, bus_dma_tag_t *, bus_dmamap_t *,
@ -264,15 +254,6 @@ static counter_u64_t extfree_rels;
void
t4_sge_modload(void)
{
int pad;
/* set pad to a reasonable powerof2 between 16 and 4096 (inclusive) */
#if defined(__i386__) || defined(__amd64__)
pad = max(cpu_clflush_line_size, 16);
#else
pad = max(CACHE_LINE_SIZE, 16);
#endif
pad = min(pad, 4096);
if (fl_pktshift < 0 || fl_pktshift > 7) {
printf("Invalid hw.cxgbe.fl_pktshift value (%d),"
@ -280,35 +261,6 @@ t4_sge_modload(void)
fl_pktshift = 2;
}
if (fl_pad != 0 &&
(fl_pad < 32 || fl_pad > 4096 || !powerof2(fl_pad))) {
if (fl_pad != -1) {
printf("Invalid hw.cxgbe.fl_pad value (%d),"
" using %d instead.\n", fl_pad, max(pad, 32));
}
fl_pad = max(pad, 32);
}
/*
* T4 has the same pad and pack boundary. If a pad boundary is set,
* pack boundary must be set to the same value. Otherwise take the
* specified value or auto-calculate something reasonable.
*/
if (fl_pad)
t4_fl_pack = fl_pad;
else if (fl_pack < 32 || fl_pack > 4096 || !powerof2(fl_pack))
t4_fl_pack = max(pad, 32);
else
t4_fl_pack = fl_pack;
/* T5's pack boundary is independent of the pad boundary. */
if (fl_pack < 16 || fl_pack == 32 || fl_pack > 4096 ||
!powerof2(fl_pack))
t5_fl_pack = max(pad, CACHE_LINE_SIZE);
else
t5_fl_pack = fl_pack;
if (spg_len != 64 && spg_len != 128) {
int len;
@ -366,6 +318,71 @@ t4_init_sge_cpl_handlers(struct adapter *sc)
t4_register_fw_msg_handler(sc, FW6_TYPE_CMD_RPL, t4_handle_fw_rpl);
}
static inline void
setup_pad_and_pack_boundaries(struct adapter *sc)
{
uint32_t v, m;
int pad, pack;
pad = fl_pad;
if (fl_pad < 32 || fl_pad > 4096 || !powerof2(fl_pad)) {
/*
* If there is any chance that we might use buffer packing and
* the chip is a T4, then pick 64 as the pad/pack boundary. Set
* it to 32 in all other cases.
*/
pad = is_t4(sc) && buffer_packing ? 64 : 32;
/*
* For fl_pad = 0 we'll still write a reasonable value to the
* register but all the freelists will opt out of padding.
* We'll complain here only if the user tried to set it to a
* value greater than 0 that was invalid.
*/
if (fl_pad > 0) {
device_printf(sc->dev, "Invalid hw.cxgbe.fl_pad value"
" (%d), using %d instead.\n", fl_pad, pad);
}
}
m = V_INGPADBOUNDARY(M_INGPADBOUNDARY);
v = V_INGPADBOUNDARY(ilog2(pad) - 5);
t4_set_reg_field(sc, A_SGE_CONTROL, m, v);
if (is_t4(sc)) {
if (fl_pack != -1 && fl_pack != pad) {
/* Complain but carry on. */
device_printf(sc->dev, "hw.cxgbe.fl_pack (%d) ignored,"
" using %d instead.\n", fl_pack, pad);
}
return;
}
pack = fl_pack;
if (fl_pack < 16 || fl_pack == 32 || fl_pack > 4096 ||
!powerof2(fl_pack)) {
pack = max(sc->params.pci.mps, CACHE_LINE_SIZE);
MPASS(powerof2(pack));
if (pack < 16)
pack = 16;
if (pack == 32)
pack = 64;
if (pack > 4096)
pack = 4096;
if (fl_pack != -1) {
device_printf(sc->dev, "Invalid hw.cxgbe.fl_pack value"
" (%d), using %d instead.\n", fl_pack, pack);
}
}
m = V_INGPACKBOUNDARY(M_INGPACKBOUNDARY);
if (pack == 16)
v = V_INGPACKBOUNDARY(0);
else
v = V_INGPACKBOUNDARY(ilog2(pack) - 5);
MPASS(!is_t4(sc)); /* T4 doesn't have SGE_CONTROL2 */
t4_set_reg_field(sc, A_SGE_CONTROL2, m, v);
}
/*
* adap->params.vpd.cclk must be set up before this is called.
*/
@ -398,24 +415,9 @@ t4_tweak_chip_settings(struct adapter *sc)
m = V_PKTSHIFT(M_PKTSHIFT) | F_RXPKTCPLMODE | F_EGRSTATUSPAGESIZE;
v = V_PKTSHIFT(fl_pktshift) | F_RXPKTCPLMODE |
V_EGRSTATUSPAGESIZE(spg_len == 128);
if (is_t4(sc) && (fl_pad || buffer_packing)) {
/* t4_fl_pack has the correct value even when fl_pad = 0 */
m |= V_INGPADBOUNDARY(M_INGPADBOUNDARY);
v |= V_INGPADBOUNDARY(ilog2(t4_fl_pack) - 5);
} else if (is_t5(sc) && fl_pad) {
m |= V_INGPADBOUNDARY(M_INGPADBOUNDARY);
v |= V_INGPADBOUNDARY(ilog2(fl_pad) - 5);
}
t4_set_reg_field(sc, A_SGE_CONTROL, m, v);
if (is_t5(sc) && buffer_packing) {
m = V_INGPACKBOUNDARY(M_INGPACKBOUNDARY);
if (t5_fl_pack == 16)
v = V_INGPACKBOUNDARY(0);
else
v = V_INGPACKBOUNDARY(ilog2(t5_fl_pack) - 5);
t4_set_reg_field(sc, A_SGE_CONTROL2, m, v);
}
setup_pad_and_pack_boundaries(sc);
v = V_HOSTPAGESIZEPF0(PAGE_SHIFT - 10) |
V_HOSTPAGESIZEPF1(PAGE_SHIFT - 10) |
@ -486,13 +488,16 @@ t4_tweak_chip_settings(struct adapter *sc)
}
/*
* SGE wants the buffer to be at least 64B and then a multiple of the pad
* boundary or 16, whichever is greater.
* SGE wants the buffer to be at least 64B and then a multiple of 16. If
* padding is is use the buffer's start and end need to be aligned to the pad
* boundary as well. We'll just make sure that the size is a multiple of the
* boundary here, it is up to the buffer allocation code to make sure the start
* of the buffer is aligned as well.
*/
static inline int
hwsz_ok(int hwsz)
hwsz_ok(struct adapter *sc, int hwsz)
{
int mask = max(fl_pad, 16) - 1;
int mask = fl_pad ? sc->sge.pad_boundary - 1 : 16 - 1;
return (hwsz >= 64 && (hwsz & mask) == 0);
}
@ -521,33 +526,22 @@ t4_read_chip_settings(struct adapter *sc)
m = V_PKTSHIFT(M_PKTSHIFT) | F_RXPKTCPLMODE | F_EGRSTATUSPAGESIZE;
v = V_PKTSHIFT(fl_pktshift) | F_RXPKTCPLMODE |
V_EGRSTATUSPAGESIZE(spg_len == 128);
if (is_t4(sc) && (fl_pad || buffer_packing)) {
m |= V_INGPADBOUNDARY(M_INGPADBOUNDARY);
v |= V_INGPADBOUNDARY(ilog2(t4_fl_pack) - 5);
} else if (is_t5(sc) && fl_pad) {
m |= V_INGPADBOUNDARY(M_INGPADBOUNDARY);
v |= V_INGPADBOUNDARY(ilog2(fl_pad) - 5);
}
r = t4_read_reg(sc, A_SGE_CONTROL);
if ((r & m) != v) {
device_printf(sc->dev, "invalid SGE_CONTROL(0x%x)\n", r);
rc = EINVAL;
}
s->pad_boundary = 1 << (G_INGPADBOUNDARY(r) + 5);
if (is_t5(sc) && buffer_packing) {
m = V_INGPACKBOUNDARY(M_INGPACKBOUNDARY);
if (t5_fl_pack == 16)
v = V_INGPACKBOUNDARY(0);
else
v = V_INGPACKBOUNDARY(ilog2(t5_fl_pack) - 5);
if (is_t4(sc))
s->pack_boundary = s->pad_boundary;
else {
r = t4_read_reg(sc, A_SGE_CONTROL2);
if ((r & m) != v) {
device_printf(sc->dev,
"invalid SGE_CONTROL2(0x%x)\n", r);
rc = EINVAL;
}
if (G_INGPACKBOUNDARY(r) == 0)
s->pack_boundary = 16;
else
s->pack_boundary = 1 << (G_INGPACKBOUNDARY(r) + 5);
}
s->pack_boundary = is_t4(sc) ? t4_fl_pack : t5_fl_pack;
v = V_HOSTPAGESIZEPF0(PAGE_SHIFT - 10) |
V_HOSTPAGESIZEPF1(PAGE_SHIFT - 10) |
@ -568,13 +562,22 @@ t4_read_chip_settings(struct adapter *sc)
for (i = 0; i < nitems(s->hw_buf_info); i++, hwb++) {
r = t4_read_reg(sc, A_SGE_FL_BUFFER_SIZE0 + (4 * i));
hwb->size = r;
hwb->zidx = hwsz_ok(r) ? -1 : -2;
hwb->zidx = hwsz_ok(sc, r) ? -1 : -2;
hwb->next = -1;
}
/*
* Create a sorted list in decreasing order of hw buffer sizes (and so
* increasing order of spare area) for each software zone.
*
* If padding is enabled then the start and end of the buffer must align
* to the pad boundary; if packing is enabled then they must align with
* the pack boundary as well. Allocations from the cluster zones are
* aligned to min(size, 4K), so the buffer starts at that alignment and
* ends at hwb->size alignment. If mbuf inlining is allowed the
* starting alignment will be reduced to MSIZE and the driver will
* exercise appropriate caution when deciding on the best buffer layout
* to use.
*/
n = 0; /* no usable buffer size to begin with */
swz = &s->sw_zone_info[0];
@ -586,6 +589,12 @@ t4_read_chip_settings(struct adapter *sc)
swz->zone = m_getzone(swz->size);
swz->type = m_gettype(swz->size);
if (swz->size < PAGE_SIZE) {
MPASS(powerof2(swz->size));
if (fl_pad && (swz->size % sc->sge.pad_boundary != 0))
continue;
}
if (swz->size == safest_rx_cluster)
safe_swz = swz;
@ -593,6 +602,10 @@ t4_read_chip_settings(struct adapter *sc)
for (j = 0; j < SGE_FLBUF_SIZES; j++, hwb++) {
if (hwb->zidx != -1 || hwb->size > swz->size)
continue;
#ifdef INVARIANTS
if (fl_pad)
MPASS(hwb->size % sc->sge.pad_boundary == 0);
#endif
hwb->zidx = i;
if (head == -1)
head = tail = j;
@ -640,14 +653,15 @@ t4_read_chip_settings(struct adapter *sc)
int spare;
hwb = &s->hw_buf_info[i];
#ifdef INVARIANTS
if (fl_pad)
MPASS(hwb->size % sc->sge.pad_boundary == 0);
#endif
spare = safe_swz->size - hwb->size;
if (spare < CL_METADATA_SIZE)
continue;
if (s->safe_hwidx2 == -1 ||
spare == CL_METADATA_SIZE + MSIZE)
if (spare >= CL_METADATA_SIZE) {
s->safe_hwidx2 = i;
if (spare >= CL_METADATA_SIZE + MSIZE)
break;
}
}
}
@ -745,17 +759,6 @@ t4_create_dma_tag(struct adapter *sc)
return (rc);
}
static inline int
enable_buffer_packing(struct adapter *sc)
{
if (sc->flags & BUF_PACKING_OK &&
((is_t5(sc) && buffer_packing) || /* 1 or -1 both ok for T5 */
(is_t4(sc) && buffer_packing == 1)))
return (1);
return (0);
}
void
t4_sge_sysctls(struct adapter *sc, struct sysctl_ctx_list *ctx,
struct sysctl_oid_list *children)
@ -769,7 +772,7 @@ t4_sge_sysctls(struct adapter *sc, struct sysctl_ctx_list *ctx,
NULL, fl_pktshift, "payload DMA offset in rx buffer (bytes)");
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "fl_pad", CTLFLAG_RD,
NULL, fl_pad, "payload pad boundary (bytes)");
NULL, sc->sge.pad_boundary, "payload pad boundary (bytes)");
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "spg_len", CTLFLAG_RD,
NULL, spg_len, "status page size (bytes)");
@ -777,10 +780,6 @@ t4_sge_sysctls(struct adapter *sc, struct sysctl_ctx_list *ctx,
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "cong_drop", CTLFLAG_RD,
NULL, cong_drop, "congestion drop setting");
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "buffer_packing", CTLFLAG_RD,
NULL, enable_buffer_packing(sc),
"pack multiple frames in one fl buffer");
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "fl_pack", CTLFLAG_RD,
NULL, sc->sge.pack_boundary, "payload pack boundary (bytes)");
}
@ -958,7 +957,6 @@ mtu_to_max_payload(struct adapter *sc, int mtu, const int toe)
#ifdef TCP_OFFLOAD
}
#endif
payload = roundup2(payload, fl_pad);
return (payload);
}
@ -983,7 +981,7 @@ t4_setup_port_queues(struct port_info *pi)
struct ifnet *ifp = pi->ifp;
struct sysctl_oid *oid = device_get_sysctl_tree(pi->dev);
struct sysctl_oid_list *children = SYSCTL_CHILDREN(oid);
int maxp, pack, mtu = ifp->if_mtu;
int maxp, mtu = ifp->if_mtu;
/* Interrupt vector to start from (when using multiple vectors) */
intr_idx = first_vector(pi);
@ -994,7 +992,6 @@ t4_setup_port_queues(struct port_info *pi)
* b) allocate queue iff it will take direct interrupts.
*/
maxp = mtu_to_max_payload(sc, mtu, 0);
pack = enable_buffer_packing(sc);
if (pi->flags & INTR_RXQ) {
oid = SYSCTL_ADD_NODE(&pi->ctx, children, OID_AUTO, "rxq",
CTLFLAG_RD, NULL, "rx queues");
@ -1005,7 +1002,7 @@ t4_setup_port_queues(struct port_info *pi)
snprintf(name, sizeof(name), "%s rxq%d-fl",
device_get_nameunit(pi->dev), i);
init_fl(sc, &rxq->fl, pi->qsize_rxq / 8, maxp, pack, name);
init_fl(sc, &rxq->fl, pi->qsize_rxq / 8, maxp, name);
if (pi->flags & INTR_RXQ) {
rxq->iq.flags |= IQ_INTR;
@ -1029,7 +1026,7 @@ t4_setup_port_queues(struct port_info *pi)
snprintf(name, sizeof(name), "%s ofld_rxq%d-fl",
device_get_nameunit(pi->dev), i);
init_fl(sc, &ofld_rxq->fl, pi->qsize_rxq / 8, maxp, pack, name);
init_fl(sc, &ofld_rxq->fl, pi->qsize_rxq / 8, maxp, name);
if (pi->flags & INTR_OFLD_RXQ) {
ofld_rxq->iq.flags |= IQ_INTR;
@ -1560,7 +1557,8 @@ rxb_free(struct mbuf *m, void *arg1, void *arg2)
* d) m_extaddref (cluster with metadata) zone_mbuf
*/
static struct mbuf *
get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int total, int flags)
get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int fr_offset,
int remaining)
{
struct mbuf *m;
struct fl_sdesc *sd = &fl->sdesc[fl->cidx];
@ -1568,12 +1566,23 @@ get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int total, int flags)
struct sw_zone_info *swz = &sc->sge.sw_zone_info[cll->zidx];
struct hw_buf_info *hwb = &sc->sge.hw_buf_info[cll->hwidx];
struct cluster_metadata *clm = cl_metadata(sc, fl, cll, sd->cl);
int len, padded_len;
int len, blen;
caddr_t payload;
len = min(total, hwb->size - fl->rx_offset);
padded_len = roundup2(len, fl->buf_boundary);
blen = hwb->size - fl->rx_offset; /* max possible in this buf */
len = min(remaining, blen);
payload = sd->cl + cll->region1 + fl->rx_offset;
if (fl->flags & FL_BUF_PACKING) {
const u_int l = fr_offset + len;
const u_int pad = roundup2(l, fl->buf_boundary) - l;
if (fl->rx_offset + len + pad < hwb->size)
blen = len + pad;
MPASS(fl->rx_offset + blen <= hwb->size);
} else {
MPASS(fl->rx_offset == 0); /* not packing */
}
if (sc->sc_do_rxcopy && len < RX_COPY_THRESHOLD) {
@ -1581,7 +1590,7 @@ get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int total, int flags)
* Copy payload into a freshly allocated mbuf.
*/
m = flags & M_PKTHDR ?
m = fr_offset == 0 ?
m_gethdr(M_NOWAIT, MT_DATA) : m_get(M_NOWAIT, MT_DATA);
if (m == NULL)
return (NULL);
@ -1603,10 +1612,11 @@ get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int total, int flags)
MPASS(clm != NULL);
m = (struct mbuf *)(sd->cl + sd->nmbuf * MSIZE);
/* No bzero required */
if (m_init(m, NULL, 0, M_NOWAIT, MT_DATA, flags | M_NOFREE))
if (m_init(m, NULL, 0, M_NOWAIT, MT_DATA,
fr_offset == 0 ? M_PKTHDR | M_NOFREE : M_NOFREE))
return (NULL);
fl->mbuf_inlined++;
m_extaddref(m, payload, padded_len, &clm->refcount, rxb_free,
m_extaddref(m, payload, blen, &clm->refcount, rxb_free,
swz->zone, sd->cl);
if (sd->nmbuf++ == 0)
counter_u64_add(extfree_refs, 1);
@ -1618,13 +1628,13 @@ get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int total, int flags)
* payload in the cluster.
*/
m = flags & M_PKTHDR ?
m = fr_offset == 0 ?
m_gethdr(M_NOWAIT, MT_DATA) : m_get(M_NOWAIT, MT_DATA);
if (m == NULL)
return (NULL);
fl->mbuf_allocated++;
if (clm != NULL) {
m_extaddref(m, payload, padded_len, &clm->refcount,
m_extaddref(m, payload, blen, &clm->refcount,
rxb_free, swz->zone, sd->cl);
if (sd->nmbuf++ == 0)
counter_u64_add(extfree_refs, 1);
@ -1633,12 +1643,12 @@ get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int total, int flags)
sd->cl = NULL; /* consumed, not a recycle candidate */
}
}
if (flags & M_PKTHDR)
m->m_pkthdr.len = total;
if (fr_offset == 0)
m->m_pkthdr.len = remaining;
m->m_len = len;
if (fl->flags & FL_BUF_PACKING) {
fl->rx_offset += padded_len;
fl->rx_offset += blen;
MPASS(fl->rx_offset <= hwb->size);
if (fl->rx_offset < hwb->size)
return (m); /* without advancing the cidx */
@ -1660,17 +1670,17 @@ static struct mbuf *
get_fl_payload(struct adapter *sc, struct sge_fl *fl, uint32_t len_newbuf)
{
struct mbuf *m0, *m, **pnext;
u_int len;
u_int remaining;
const u_int total = G_RSPD_LEN(len_newbuf);
len = G_RSPD_LEN(len_newbuf);
if (__predict_false(fl->flags & FL_BUF_RESUME)) {
M_ASSERTPKTHDR(fl->m0);
MPASS(len == fl->m0->m_pkthdr.len);
MPASS(fl->remaining < len);
MPASS(fl->m0->m_pkthdr.len == total);
MPASS(fl->remaining < total);
m0 = fl->m0;
pnext = fl->pnext;
len = fl->remaining;
remaining = fl->remaining;
fl->flags &= ~FL_BUF_RESUME;
goto get_segment;
}
@ -1691,25 +1701,25 @@ get_fl_payload(struct adapter *sc, struct sge_fl *fl, uint32_t len_newbuf)
* 'len' and it may span multiple hw buffers.
*/
m0 = get_scatter_segment(sc, fl, len, M_PKTHDR);
m0 = get_scatter_segment(sc, fl, 0, total);
if (m0 == NULL)
return (NULL);
len -= m0->m_len;
remaining = total - m0->m_len;
pnext = &m0->m_next;
while (len > 0) {
while (remaining > 0) {
get_segment:
MPASS(fl->rx_offset == 0);
m = get_scatter_segment(sc, fl, len, 0);
m = get_scatter_segment(sc, fl, total - remaining, remaining);
if (__predict_false(m == NULL)) {
fl->m0 = m0;
fl->pnext = pnext;
fl->remaining = len;
fl->remaining = remaining;
fl->flags |= FL_BUF_RESUME;
return (NULL);
}
*pnext = m;
pnext = &m->m_next;
len -= m->m_len;
remaining -= m->m_len;
}
*pnext = NULL;
@ -2121,14 +2131,15 @@ init_iq(struct sge_iq *iq, struct adapter *sc, int tmr_idx, int pktc_idx,
}
static inline void
init_fl(struct adapter *sc, struct sge_fl *fl, int qsize, int maxp, int pack,
char *name)
init_fl(struct adapter *sc, struct sge_fl *fl, int qsize, int maxp, char *name)
{
fl->qsize = qsize;
fl->sidx = qsize - spg_len / EQ_ESIZE;
strlcpy(fl->lockname, name, sizeof(fl->lockname));
if (pack)
if (sc->flags & BUF_PACKING_OK &&
((!is_t4(sc) && buffer_packing) || /* T5+: enabled unless 0 */
(is_t4(sc) && buffer_packing == 1)))/* T4: disabled unless 1 */
fl->flags |= FL_BUF_PACKING;
find_best_refill_source(sc, fl, maxp);
find_safe_refill_source(sc, fl);
@ -2277,11 +2288,13 @@ alloc_iq_fl(struct port_info *pi, struct sge_iq *iq, struct sge_fl *fl,
if (fl->flags & FL_BUF_PACKING) {
fl->lowat = roundup2(sc->sge.fl_starve_threshold2, 8);
fl->buf_boundary = max(fl_pad, sc->sge.pack_boundary);
fl->buf_boundary = sc->sge.pack_boundary;
} else {
fl->lowat = roundup2(sc->sge.fl_starve_threshold, 8);
fl->buf_boundary = fl_pad;
fl->buf_boundary = 16;
}
if (fl_pad && fl->buf_boundary < sc->sge.pad_boundary)
fl->buf_boundary = sc->sge.pad_boundary;
c.iqns_to_fl0congen |=
htobe32(V_FW_IQ_CMD_FL0HOSTFCMODE(X_HOSTFCMODE_NONE) |
@ -2452,6 +2465,10 @@ add_fl_sysctls(struct sysctl_ctx_list *ctx, struct sysctl_oid *oid,
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cntxt_id",
CTLTYPE_INT | CTLFLAG_RD, &fl->cntxt_id, 0, sysctl_uint16, "I",
"SGE context id of the freelist");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "padding", CTLFLAG_RD, NULL,
fl_pad ? 1 : 0, "padding enabled");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "packing", CTLFLAG_RD, NULL,
fl->flags & FL_BUF_PACKING ? 1 : 0, "packing enabled");
SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "cidx", CTLFLAG_RD, &fl->cidx,
0, "consumer index");
if (fl->flags & FL_BUF_PACKING) {
@ -4367,6 +4384,17 @@ find_best_refill_source(struct adapter *sc, struct sge_fl *fl, int maxp)
if (allow_mbufs_in_cluster == 0 || hwb->size < maxp)
break;
/*
* Do not inline mbufs if doing so would violate the pad/pack
* boundary alignment requirement.
*/
if (fl_pad && (MSIZE % sc->sge.pad_boundary) != 0)
continue;
if (fl->flags & FL_BUF_PACKING &&
(MSIZE % sc->sge.pack_boundary) != 0)
continue;
if (spare < CL_METADATA_SIZE + MSIZE)
continue;
n = (spare - CL_METADATA_SIZE) / MSIZE;
@ -4449,7 +4477,8 @@ find_safe_refill_source(struct adapter *sc, struct sge_fl *fl)
spare = swz->size - hwb->size;
fl->cll_alt.hwidx = hwidx;
fl->cll_alt.zidx = hwb->zidx;
if (allow_mbufs_in_cluster)
if (allow_mbufs_in_cluster &&
(fl_pad == 0 || (MSIZE % sc->sge.pad_boundary) == 0))
fl->cll_alt.region1 = ((spare - CL_METADATA_SIZE) / MSIZE) * MSIZE;
else
fl->cll_alt.region1 = 0;

View File

@ -58,6 +58,7 @@
#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/priv.h>
#include <sys/libkern.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@ -216,7 +217,7 @@ static uint8_t
saf1761_host_channel_alloc(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
{
uint32_t map;
uint32_t x;
int x;
if (td->channel < SOTG_HOST_CHANNEL_MAX)
return (0);
@ -227,41 +228,38 @@ saf1761_host_channel_alloc(struct saf1761_otg_softc *sc, struct saf1761_otg_td *
switch (td->ep_type) {
case UE_INTERRUPT:
map = sc->sc_host_intr_map |
map = ~(sc->sc_host_intr_map |
sc->sc_host_intr_busy_map[0] |
sc->sc_host_intr_busy_map[1];
for (x = ((map & 0xFFFF) == 0xFFFF) ? 16 : 0; x != 32; x++) {
if (map & (1 << x))
continue;
sc->sc_host_intr_map |= (1 << x);
td->channel = 32 + x;
return (0);
}
break;
sc->sc_host_intr_busy_map[1]);
/* find first set bit */
x = ffs(map) - 1;
if (x < 0 || x > 31)
break;
sc->sc_host_intr_map |= (1U << x);
td->channel = 32 + x;
return (0);
case UE_ISOCHRONOUS:
map = sc->sc_host_isoc_map |
map = ~(sc->sc_host_isoc_map |
sc->sc_host_isoc_busy_map[0] |
sc->sc_host_isoc_busy_map[1];
for (x = ((map & 0xFFFF) == 0xFFFF) ? 16 : 0; x != 32; x++) {
if (map & (1 << x))
continue;
sc->sc_host_isoc_map |= (1 << x);
td->channel = x;
return (0);
}
break;
sc->sc_host_isoc_busy_map[1]);
/* find first set bit */
x = ffs(map) - 1;
if (x < 0 || x > 31)
break;
sc->sc_host_isoc_map |= (1U << x);
td->channel = x;
return (0);
default:
map = sc->sc_host_async_map |
map = ~(sc->sc_host_async_map |
sc->sc_host_async_busy_map[0] |
sc->sc_host_async_busy_map[1];
for (x = ((map & 0xFFFF) == 0xFFFF) ? 16 : 0; x != 32; x++) {
if (map & (1 << x))
continue;
sc->sc_host_async_map |= (1 << x);
td->channel = 64 + x;
return (0);
}
break;
sc->sc_host_async_busy_map[1]);
/* find first set bit */
x = ffs(map) - 1;
if (x < 0 || x > 31)
break;
sc->sc_host_async_map |= (1U << x);
td->channel = 64 + x;
return (0);
}
return (1);
}
@ -278,27 +276,27 @@ saf1761_host_channel_free(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
case UE_INTERRUPT:
x = td->channel - 32;
td->channel = SOTG_HOST_CHANNEL_MAX;
sc->sc_host_intr_map &= ~(1 << x);
sc->sc_host_intr_suspend_map &= ~(1 << x);
sc->sc_host_intr_busy_map[0] |= (1 << x);
sc->sc_host_intr_map &= ~(1U << x);
sc->sc_host_intr_suspend_map &= ~(1U << x);
sc->sc_host_intr_busy_map[0] |= (1U << x);
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
(~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
break;
case UE_ISOCHRONOUS:
x = td->channel;
td->channel = SOTG_HOST_CHANNEL_MAX;
sc->sc_host_isoc_map &= ~(1 << x);
sc->sc_host_isoc_suspend_map &= ~(1 << x);
sc->sc_host_isoc_busy_map[0] |= (1 << x);
sc->sc_host_isoc_map &= ~(1U << x);
sc->sc_host_isoc_suspend_map &= ~(1U << x);
sc->sc_host_isoc_busy_map[0] |= (1U << x);
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
(~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
break;
default:
x = td->channel - 64;
td->channel = SOTG_HOST_CHANNEL_MAX;
sc->sc_host_async_map &= ~(1 << x);
sc->sc_host_async_suspend_map &= ~(1 << x);
sc->sc_host_async_busy_map[0] |= (1 << x);
sc->sc_host_async_map &= ~(1U << x);
sc->sc_host_async_suspend_map &= ~(1U << x);
sc->sc_host_async_busy_map[0] |= (1U << x);
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
(~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
break;
@ -3619,19 +3617,19 @@ saf1761_otg_device_resume(struct usb_device *udev)
switch (td->ep_type) {
case UE_INTERRUPT:
x = td->channel - 32;
sc->sc_host_intr_suspend_map &= ~(1 << x);
sc->sc_host_intr_suspend_map &= ~(1U << x);
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
(~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
break;
case UE_ISOCHRONOUS:
x = td->channel;
sc->sc_host_isoc_suspend_map &= ~(1 << x);
sc->sc_host_isoc_suspend_map &= ~(1U << x);
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
(~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
break;
default:
x = td->channel - 64;
sc->sc_host_async_suspend_map &= ~(1 << x);
sc->sc_host_async_suspend_map &= ~(1U << x);
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
(~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
break;
@ -3675,19 +3673,19 @@ saf1761_otg_device_suspend(struct usb_device *udev)
switch (td->ep_type) {
case UE_INTERRUPT:
x = td->channel - 32;
sc->sc_host_intr_suspend_map |= (1 << x);
sc->sc_host_intr_suspend_map |= (1U << x);
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
(~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
break;
case UE_ISOCHRONOUS:
x = td->channel;
sc->sc_host_isoc_suspend_map |= (1 << x);
sc->sc_host_isoc_suspend_map |= (1U << x);
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
(~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
break;
default:
x = td->channel - 64;
sc->sc_host_async_suspend_map |= (1 << x);
sc->sc_host_async_suspend_map |= (1U << x);
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
(~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
break;

View File

@ -256,23 +256,24 @@ nvidia_meta_read(struct g_consumer *cp)
pp->name, error);
return (NULL);
}
meta = malloc(sizeof(*meta), M_MD_NVIDIA, M_WAITOK);
memcpy(meta, buf, min(sizeof(*meta), pp->sectorsize));
g_free(buf);
meta = (struct nvidia_raid_conf *)buf;
/* Check if this is an NVIDIA RAID struct */
if (strncmp(meta->nvidia_id, NVIDIA_MAGIC, strlen(NVIDIA_MAGIC))) {
G_RAID_DEBUG(1, "NVIDIA signature check failed on %s", pp->name);
free(meta, M_MD_NVIDIA);
g_free(buf);
return (NULL);
}
if (meta->config_size > 128 ||
meta->config_size < 30) {
G_RAID_DEBUG(1, "NVIDIA metadata size looks wrong: %d",
meta->config_size);
free(meta, M_MD_NVIDIA);
g_free(buf);
return (NULL);
}
meta = malloc(sizeof(*meta), M_MD_NVIDIA, M_WAITOK);
memcpy(meta, buf, min(sizeof(*meta), pp->sectorsize));
g_free(buf);
/* Check metadata checksum. */
for (checksum = 0, ptr = (uint32_t *)meta,

View File

@ -277,15 +277,13 @@ sii_meta_read(struct g_consumer *cp)
pp->name, error);
return (NULL);
}
meta = malloc(sizeof(*meta), M_MD_SII, M_WAITOK);
memcpy(meta, buf, min(sizeof(*meta), pp->sectorsize));
g_free(buf);
meta = (struct sii_raid_conf *)buf;
/* Check vendor ID. */
if (meta->vendor_id != 0x1095) {
G_RAID_DEBUG(1, "SiI vendor ID check failed on %s (0x%04x)",
pp->name, meta->vendor_id);
free(meta, M_MD_SII);
g_free(buf);
return (NULL);
}
@ -293,9 +291,12 @@ sii_meta_read(struct g_consumer *cp)
if (meta->version_major != 2) {
G_RAID_DEBUG(1, "SiI version check failed on %s (%d.%d)",
pp->name, meta->version_major, meta->version_minor);
free(meta, M_MD_SII);
g_free(buf);
return (NULL);
}
meta = malloc(sizeof(*meta), M_MD_SII, M_WAITOK);
memcpy(meta, buf, min(sizeof(*meta), pp->sectorsize));
g_free(buf);
/* Check metadata checksum. */
for (checksum = 0, ptr = (uint16_t *)meta, i = 0; i <= 159; i++)

View File

@ -54,11 +54,6 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/smp.h>
#ifdef KDTRACE_HOOKS
#include <sys/dtrace_bsd.h>
cyclic_clock_func_t cyclic_clock_func = NULL;
#endif
int cpu_can_deep_sleep = 0; /* C3 state is available. */
int cpu_disable_deep_sleep = 0; /* Timer dies in C3. */
@ -125,9 +120,6 @@ struct pcpu_state {
sbintime_t nextprof; /* Next profclock() event. */
sbintime_t nextcall; /* Next callout event. */
sbintime_t nextcallopt; /* Next optional callout event. */
#ifdef KDTRACE_HOOKS
sbintime_t nextcyc; /* Next OpenSolaris cyclics event. */
#endif
int ipi; /* This CPU needs IPI. */
int idle; /* This CPU is in idle mode. */
};
@ -219,13 +211,6 @@ handleevents(sbintime_t now, int fake)
callout_process(now);
}
#ifdef KDTRACE_HOOKS
if (fake == 0 && now >= state->nextcyc && cyclic_clock_func != NULL) {
state->nextcyc = SBT_MAX;
(*cyclic_clock_func)(frame);
}
#endif
t = getnextcpuevent(0);
ET_HW_LOCK(state);
if (!busy) {
@ -271,10 +256,6 @@ getnextcpuevent(int idle)
if (profiling && event > state->nextprof)
event = state->nextprof;
}
#ifdef KDTRACE_HOOKS
if (event > state->nextcyc)
event = state->nextcyc;
#endif
return (event);
}
@ -595,9 +576,6 @@ cpu_initclocks_bsp(void)
CPU_FOREACH(cpu) {
state = DPCPU_ID_PTR(cpu, timerstate);
mtx_init(&state->et_hw_mtx, "et_hw_mtx", NULL, MTX_SPIN);
#ifdef KDTRACE_HOOKS
state->nextcyc = SBT_MAX;
#endif
state->nextcall = SBT_MAX;
state->nextcallopt = SBT_MAX;
}
@ -816,41 +794,6 @@ cpu_et_frequency(struct eventtimer *et, uint64_t newfreq)
ET_UNLOCK();
}
#ifdef KDTRACE_HOOKS
void
clocksource_cyc_set(const struct bintime *bt)
{
sbintime_t now, t;
struct pcpu_state *state;
/* Do not touch anything if somebody reconfiguring timers. */
if (busy)
return;
t = bttosbt(*bt);
state = DPCPU_PTR(timerstate);
if (periodic)
now = state->now;
else
now = sbinuptime();
CTR5(KTR_SPARE2, "set_cyc at %d: now %d.%08x t %d.%08x",
curcpu, (int)(now >> 32), (u_int)(now & 0xffffffff),
(int)(t >> 32), (u_int)(t & 0xffffffff));
ET_HW_LOCK(state);
if (t == state->nextcyc)
goto done;
state->nextcyc = t;
if (t >= state->nextevent)
goto done;
state->nextevent = t;
if (!periodic)
loadtimer(now, 0);
done:
ET_HW_UNLOCK(state);
}
#endif
void
cpu_new_callout(int cpu, sbintime_t bt, sbintime_t bt_opt)
{

View File

@ -31,6 +31,7 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.syntax unified
/*
* ffs - find first set bit, this algorithm isolates the first set
@ -62,7 +63,7 @@ ENTRY(ffs)
rsbne r0, r0, r0, lsl #16 /* r0 = X * 0x0450fbaf */
/* now lookup in table indexed on top 6 bits of r0 */
ldrneb r0, [ r2, r0, lsr #26 ]
ldrbne r0, [ r2, r0, lsr #26 ]
RET
.text;

View File

@ -90,7 +90,6 @@ SUBDIR= \
cuse \
${_cxgb} \
${_cxgbe} \
${_cyclic} \
dc \
dcons \
dcons_crom \
@ -494,9 +493,6 @@ _cardbus= cardbus
_cbb= cbb
_cpuctl= cpuctl
_cpufreq= cpufreq
.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
_cyclic= cyclic
.endif
_dpms= dpms
_drm= drm
_drm2= drm2
@ -702,9 +698,6 @@ _cardbus= cardbus
_cbb= cbb
_cfi= cfi
_cpufreq= cpufreq
.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
_cyclic= cyclic
.endif
_drm= drm
.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
_dtrace= dtrace

View File

@ -1,21 +0,0 @@
# $FreeBSD$
SYSDIR?= ${.CURDIR}/../..
.PATH: ${SYSDIR}/cddl/dev/cyclic
KMOD= cyclic
SRCS= cyclic.c
SRCS+= vnode_if.h
CFLAGS+= -I${SYSDIR}/cddl/compat/opensolaris \
-I${SYSDIR}/cddl/contrib/opensolaris/uts/common \
-I${SYSDIR} \
-I${SYSDIR}/cddl/dev/cyclic/i386
IGNORE_PRAGMA= 1
.include <bsd.kmod.mk>
CFLAGS+= -include ${SYSDIR}/cddl/compat/opensolaris/sys/debug_compat.h

View File

@ -3,7 +3,6 @@
IGNORE_PRAGMA= 1
load :
-kldload cyclic
-kldload dtrace
.if ${MACHINE_CPUARCH} == "i386"
-kldload sdt
@ -25,5 +24,4 @@ unload :
-kldunload sdt
.endif
-kldunload dtrace
-kldunload cyclic
kldstat

View File

@ -63,7 +63,6 @@ DEV_MODULE(dtraceall, dtraceall_modevent, NULL);
MODULE_VERSION(dtraceall, 1);
/* All the DTrace modules should be dependencies here: */
MODULE_DEPEND(dtraceall, cyclic, 1, 1, 1);
MODULE_DEPEND(dtraceall, opensolaris, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtrace, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtmalloc, 1, 1, 1);

View File

@ -5477,10 +5477,12 @@ __attribute__((noinline))
if ((ch->chunk_type & 0x40) && (stcb != NULL)) {
struct mbuf *mm;
struct sctp_paramhdr *phd;
int len;
mm = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
0, M_NOWAIT, 1, MT_DATA);
if (mm) {
len = min(SCTP_SIZE32(chk_length), (uint32_t) (length - *offset));
phd = mtod(mm, struct sctp_paramhdr *);
/*
* We cheat and use param type since
@ -5490,11 +5492,11 @@ __attribute__((noinline))
* names.
*/
phd->param_type = htons(SCTP_CAUSE_UNRECOG_CHUNK);
phd->param_length = htons(chk_length + sizeof(*phd));
phd->param_length = htons(len + sizeof(*phd));
SCTP_BUF_LEN(mm) = sizeof(*phd);
SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset, chk_length, M_NOWAIT);
SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset, len, M_NOWAIT);
if (SCTP_BUF_NEXT(mm)) {
if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(mm), SCTP_SIZE32(chk_length) - chk_length, NULL) == NULL) {
if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(mm), SCTP_SIZE32(len) - len, NULL) == NULL) {
sctp_m_freem(mm);
} else {
#ifdef SCTP_MBUF_LOGGING

View File

@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_header.h>
#include <netinet/sctp_var.h>
#ifdef INET6
#include <netinet6/sctp6_var.h>
#endif
#include <netinet/sctp_sysctl.h>
#include <netinet/sctp_output.h>
@ -1373,10 +1374,14 @@ sctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id)
switch (sctp_ifa->address.sa.sa_family) {
#ifdef INET
case AF_INET:
#ifdef INET6
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
cnt += sizeof(struct sockaddr_in6);
else
cnt += sizeof(struct sockaddr_in);
#else
cnt += sizeof(struct sockaddr_in);
#endif
break;
#endif
#ifdef INET6
@ -1396,10 +1401,14 @@ sctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id)
switch (laddr->ifa->address.sa.sa_family) {
#ifdef INET
case AF_INET:
#ifdef INET6
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
cnt += sizeof(struct sockaddr_in6);
else
cnt += sizeof(struct sockaddr_in);
#else
cnt += sizeof(struct sockaddr_in);
#endif
break;
#endif
#ifdef INET6
@ -2216,23 +2225,27 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
size = 0;
/* Count the sizes */
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
size += sizeof(struct sockaddr_in6);
} else {
switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
switch (net->ro._l_addr.sa.sa_family) {
#ifdef INET
case AF_INET:
case AF_INET:
#ifdef INET6
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
size += sizeof(struct sockaddr_in6);
} else {
size += sizeof(struct sockaddr_in);
break;
}
#else
size += sizeof(struct sockaddr_in);
#endif
break;
#endif
#ifdef INET6
case AF_INET6:
size += sizeof(struct sockaddr_in6);
break;
case AF_INET6:
size += sizeof(struct sockaddr_in6);
break;
#endif
default:
break;
}
default:
break;
}
}
SCTP_TCB_UNLOCK(stcb);
@ -2264,24 +2277,28 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
sas = (struct sockaddr_storage *)&saddr->addr[0];
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
cpsz = sizeof(struct sockaddr_in6);
} else {
switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
switch (net->ro._l_addr.sa.sa_family) {
#ifdef INET
case AF_INET:
case AF_INET:
#ifdef INET6
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
cpsz = sizeof(struct sockaddr_in6);
} else {
cpsz = sizeof(struct sockaddr_in);
break;
}
#else
cpsz = sizeof(struct sockaddr_in);
#endif
break;
#endif
#ifdef INET6
case AF_INET6:
cpsz = sizeof(struct sockaddr_in6);
break;
case AF_INET6:
cpsz = sizeof(struct sockaddr_in6);
break;
#endif
default:
cpsz = 0;
break;
}
default:
cpsz = 0;
break;
}
if (cpsz == 0) {
break;
@ -2292,15 +2309,15 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
}
#if defined(INET) && defined(INET6)
if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) &&
(((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET)) {
(net->ro._l_addr.sa.sa_family == AF_INET)) {
/* Must map the address */
in6_sin_2_v4mapsin6((struct sockaddr_in *)&net->ro._l_addr,
in6_sin_2_v4mapsin6(&net->ro._l_addr.sin,
(struct sockaddr_in6 *)sas);
} else {
#endif
memcpy(sas, &net->ro._l_addr, cpsz);
#if defined(INET) && defined(INET6)
}
#else
memcpy(sas, &net->ro._l_addr, cpsz);
#endif
((struct sockaddr_in *)sas)->sin_port = stcb->rport;
@ -2337,13 +2354,35 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
{
struct sctp_paddrparams *paddrp;
struct sctp_nets *net;
struct sockaddr *addr;
#if defined(INET) && defined(INET6)
struct sockaddr_in sin_store;
#endif
SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, *optsize);
SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
net = NULL;
if (stcb) {
net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
#if defined(INET) && defined(INET6)
if (paddrp->spp_address.ss_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&paddrp->spp_address;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
in6_sin6_2_sin(&sin_store, sin6);
addr = (struct sockaddr *)&sin_store;
} else {
addr = (struct sockaddr *)&paddrp->spp_address;
}
} else {
addr = (struct sockaddr *)&paddrp->spp_address;
}
#else
addr = (struct sockaddr *)&paddrp->spp_address;
#endif
if (stcb != NULL) {
net = sctp_findnet(stcb, addr);
} else {
/*
* We increment here since
@ -2352,22 +2391,20 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
* the locked tcb (last argument) is NOT a
* TCB.. aka NULL.
*/
net = NULL;
SCTP_INP_INCR_REF(inp);
stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&paddrp->spp_address, &net, NULL, NULL);
stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
if (stcb == NULL) {
SCTP_INP_DECR_REF(inp);
}
}
if (stcb && (net == NULL)) {
struct sockaddr *sa;
sa = (struct sockaddr *)&paddrp->spp_address;
if ((stcb != NULL) && (net == NULL)) {
#ifdef INET
if (sa->sa_family == AF_INET) {
if (addr->sa_family == AF_INET) {
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)sa;
if (sin->sin_addr.s_addr) {
sin = (struct sockaddr_in *)addr;
if (sin->sin_addr.s_addr != INADDR_ANY) {
error = EINVAL;
SCTP_TCB_UNLOCK(stcb);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
@ -2376,10 +2413,10 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
} else
#endif
#ifdef INET6
if (sa->sa_family == AF_INET6) {
if (addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)sa;
sin6 = (struct sockaddr_in6 *)addr;
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
error = EINVAL;
SCTP_TCB_UNLOCK(stcb);
@ -2395,10 +2432,10 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
break;
}
}
if (stcb) {
if (stcb != NULL) {
/* Applies to the specific association */
paddrp->spp_flags = 0;
if (net) {
if (net != NULL) {
int ovh;
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
@ -2514,13 +2551,35 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
{
struct sctp_paddrinfo *paddri;
struct sctp_nets *net;
struct sockaddr *addr;
#if defined(INET) && defined(INET6)
struct sockaddr_in sin_store;
#endif
SCTP_CHECK_AND_CAST(paddri, optval, struct sctp_paddrinfo, *optsize);
SCTP_FIND_STCB(inp, stcb, paddri->spinfo_assoc_id);
net = NULL;
if (stcb) {
net = sctp_findnet(stcb, (struct sockaddr *)&paddri->spinfo_address);
#if defined(INET) && defined(INET6)
if (paddri->spinfo_address.ss_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&paddri->spinfo_address;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
in6_sin6_2_sin(&sin_store, sin6);
addr = (struct sockaddr *)&sin_store;
} else {
addr = (struct sockaddr *)&paddri->spinfo_address;
}
} else {
addr = (struct sockaddr *)&paddri->spinfo_address;
}
#else
addr = (struct sockaddr *)&paddri->spinfo_address;
#endif
if (stcb != NULL) {
net = sctp_findnet(stcb, addr);
} else {
/*
* We increment here since
@ -2529,14 +2588,15 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
* the locked tcb (last argument) is NOT a
* TCB.. aka NULL.
*/
net = NULL;
SCTP_INP_INCR_REF(inp);
stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&paddri->spinfo_address, &net, NULL, NULL);
stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
if (stcb == NULL) {
SCTP_INP_DECR_REF(inp);
}
}
if ((stcb) && (net)) {
if ((stcb != NULL) && (net != NULL)) {
if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
/* It's unconfirmed */
paddri->spinfo_state = SCTP_UNCONFIRMED;
@ -2555,7 +2615,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
SCTP_TCB_UNLOCK(stcb);
*optsize = sizeof(struct sctp_paddrinfo);
} else {
if (stcb) {
if (stcb != NULL) {
SCTP_TCB_UNLOCK(stcb);
}
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
@ -2772,16 +2832,32 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
SCTP_FIND_STCB(inp, stcb, ssp->ssp_assoc_id);
if (stcb) {
/* simply copy out the sockaddr_storage... */
size_t len;
union sctp_sockstore *addr;
len = *optsize;
if (len > stcb->asoc.primary_destination->ro._l_addr.sa.sa_len)
len = stcb->asoc.primary_destination->ro._l_addr.sa.sa_len;
memcpy(&ssp->ssp_addr,
&stcb->asoc.primary_destination->ro._l_addr,
len);
addr = &stcb->asoc.primary_destination->ro._l_addr;
switch (addr->sa.sa_family) {
#ifdef INET
case AF_INET:
#ifdef INET6
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
in6_sin_2_v4mapsin6(&addr->sin,
(struct sockaddr_in6 *)&ssp->ssp_addr);
} else {
memcpy(&ssp->ssp_addr, &addr->sin, sizeof(struct sockaddr_in));
}
#else
memcpy(&ssp->ssp_addr, &addr->sin, sizeof(struct sockaddr_in));
#endif
break;
#endif
#ifdef INET6
case AF_INET6:
memcpy(&ssp->ssp_addr, &addr->sin6, sizeof(struct sockaddr_in6));
break;
#endif
default:
break;
}
SCTP_TCB_UNLOCK(stcb);
*optsize = sizeof(struct sctp_setprim);
} else {
@ -3121,13 +3197,35 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
{
struct sctp_paddrthlds *thlds;
struct sctp_nets *net;
struct sockaddr *addr;
#if defined(INET) && defined(INET6)
struct sockaddr_in sin_store;
#endif
SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, *optsize);
SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
net = NULL;
if (stcb) {
net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address);
#if defined(INET) && defined(INET6)
if (thlds->spt_address.ss_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&thlds->spt_address;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
in6_sin6_2_sin(&sin_store, sin6);
addr = (struct sockaddr *)&sin_store;
} else {
addr = (struct sockaddr *)&thlds->spt_address;
}
} else {
addr = (struct sockaddr *)&thlds->spt_address;
}
#else
addr = (struct sockaddr *)&thlds->spt_address;
#endif
if (stcb != NULL) {
net = sctp_findnet(stcb, addr);
} else {
/*
* We increment here since
@ -3136,22 +3234,20 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
* the locked tcb (last argument) is NOT a
* TCB.. aka NULL.
*/
net = NULL;
SCTP_INP_INCR_REF(inp);
stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&thlds->spt_address, &net, NULL, NULL);
stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
if (stcb == NULL) {
SCTP_INP_DECR_REF(inp);
}
}
if (stcb && (net == NULL)) {
struct sockaddr *sa;
sa = (struct sockaddr *)&thlds->spt_address;
if ((stcb != NULL) && (net == NULL)) {
#ifdef INET
if (sa->sa_family == AF_INET) {
if (addr->sa_family == AF_INET) {
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)sa;
if (sin->sin_addr.s_addr) {
sin = (struct sockaddr_in *)addr;
if (sin->sin_addr.s_addr != INADDR_ANY) {
error = EINVAL;
SCTP_TCB_UNLOCK(stcb);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
@ -3160,10 +3256,10 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
} else
#endif
#ifdef INET6
if (sa->sa_family == AF_INET6) {
if (addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)sa;
sin6 = (struct sockaddr_in6 *)addr;
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
error = EINVAL;
SCTP_TCB_UNLOCK(stcb);
@ -3179,8 +3275,8 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
break;
}
}
if (stcb) {
if (net) {
if (stcb != NULL) {
if (net != NULL) {
thlds->spt_pathmaxrxt = net->failure_threshold;
thlds->spt_pathpfthld = net->pf_threshold;
} else {
@ -3212,12 +3308,35 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
{
struct sctp_udpencaps *encaps;
struct sctp_nets *net;
struct sockaddr *addr;
#if defined(INET) && defined(INET6)
struct sockaddr_in sin_store;
#endif
SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, *optsize);
SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id);
#if defined(INET) && defined(INET6)
if (encaps->sue_address.ss_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&encaps->sue_address;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
in6_sin6_2_sin(&sin_store, sin6);
addr = (struct sockaddr *)&sin_store;
} else {
addr = (struct sockaddr *)&encaps->sue_address;
}
} else {
addr = (struct sockaddr *)&encaps->sue_address;
}
#else
addr = (struct sockaddr *)&encaps->sue_address;
#endif
if (stcb) {
net = sctp_findnet(stcb, (struct sockaddr *)&encaps->sue_address);
net = sctp_findnet(stcb, addr);
} else {
/*
* We increment here since
@ -3228,21 +3347,18 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
*/
net = NULL;
SCTP_INP_INCR_REF(inp);
stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&encaps->sue_address, &net, NULL, NULL);
stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
if (stcb == NULL) {
SCTP_INP_DECR_REF(inp);
}
}
if (stcb && (net == NULL)) {
struct sockaddr *sa;
sa = (struct sockaddr *)&encaps->sue_address;
if ((stcb != NULL) && (net == NULL)) {
#ifdef INET
if (sa->sa_family == AF_INET) {
if (addr->sa_family == AF_INET) {
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)sa;
if (sin->sin_addr.s_addr) {
sin = (struct sockaddr_in *)addr;
if (sin->sin_addr.s_addr != INADDR_ANY) {
error = EINVAL;
SCTP_TCB_UNLOCK(stcb);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
@ -3251,10 +3367,10 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
} else
#endif
#ifdef INET6
if (sa->sa_family == AF_INET6) {
if (addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)sa;
sin6 = (struct sockaddr_in6 *)addr;
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
error = EINVAL;
SCTP_TCB_UNLOCK(stcb);
@ -3270,7 +3386,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
break;
}
}
if (stcb) {
if (stcb != NULL) {
if (net) {
encaps->sue_port = net->port;
} else {
@ -4946,12 +5062,35 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
{
struct sctp_paddrparams *paddrp;
struct sctp_nets *net;
struct sockaddr *addr;
#if defined(INET) && defined(INET6)
struct sockaddr_in sin_store;
#endif
SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, optsize);
SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
net = NULL;
if (stcb) {
net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
#if defined(INET) && defined(INET6)
if (paddrp->spp_address.ss_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&paddrp->spp_address;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
in6_sin6_2_sin(&sin_store, sin6);
addr = (struct sockaddr *)&sin_store;
} else {
addr = (struct sockaddr *)&paddrp->spp_address;
}
} else {
addr = (struct sockaddr *)&paddrp->spp_address;
}
#else
addr = (struct sockaddr *)&paddrp->spp_address;
#endif
if (stcb != NULL) {
net = sctp_findnet(stcb, addr);
} else {
/*
* We increment here since
@ -4960,25 +5099,22 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
* the locked tcb (last argument) is NOT a
* TCB.. aka NULL.
*/
net = NULL;
SCTP_INP_INCR_REF(inp);
stcb = sctp_findassociation_ep_addr(&inp,
(struct sockaddr *)&paddrp->spp_address,
stcb = sctp_findassociation_ep_addr(&inp, addr,
&net, NULL, NULL);
if (stcb == NULL) {
SCTP_INP_DECR_REF(inp);
}
}
if (stcb && (net == NULL)) {
struct sockaddr *sa;
sa = (struct sockaddr *)&paddrp->spp_address;
if ((stcb != NULL) && (net == NULL)) {
#ifdef INET
if (sa->sa_family == AF_INET) {
if (addr->sa_family == AF_INET) {
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)sa;
if (sin->sin_addr.s_addr) {
sin = (struct sockaddr_in *)addr;
if (sin->sin_addr.s_addr != INADDR_ANY) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
SCTP_TCB_UNLOCK(stcb);
error = EINVAL;
@ -4987,10 +5123,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
} else
#endif
#ifdef INET6
if (sa->sa_family == AF_INET6) {
if (addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)sa;
sin6 = (struct sockaddr_in6 *)addr;
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
SCTP_TCB_UNLOCK(stcb);
@ -5019,7 +5155,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
return (EINVAL);
}
if (stcb) {
if (stcb != NULL) {
/************************TCB SPECIFIC SET ******************/
/*
* do we change the timer for HB, we run
@ -5034,7 +5170,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
/* network sets ? */
if (net) {
if (net != NULL) {
/************************NET SPECIFIC SET ******************/
if (paddrp->spp_flags & SPP_HB_DISABLE) {
if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
@ -5119,7 +5255,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
#endif
} else {
/************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/
if (paddrp->spp_pathmaxrxt) {
if (paddrp->spp_pathmaxrxt != 0) {
stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt;
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
if (net->dest_state & SCTP_ADDR_PF) {
@ -5150,14 +5286,14 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
}
if (paddrp->spp_flags & SPP_HB_ENABLE) {
if (paddrp->spp_hbinterval) {
if (paddrp->spp_hbinterval != 0) {
stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval;
} else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
stcb->asoc.heart_beat_delay = 0;
}
/* Turn back on the timer */
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
if (paddrp->spp_hbinterval) {
if (paddrp->spp_hbinterval != 0) {
net->heart_beat_delay = paddrp->spp_hbinterval;
} else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
net->heart_beat_delay = 0;
@ -5238,12 +5374,12 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
* set it with the options on the
* socket
*/
if (paddrp->spp_pathmaxrxt) {
if (paddrp->spp_pathmaxrxt != 0) {
inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt;
}
if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO)
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0;
else if (paddrp->spp_hbinterval) {
else if (paddrp->spp_hbinterval != 0) {
if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL)
paddrp->spp_hbinterval = SCTP_MAX_HB_INTERVAL;
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval);
@ -5409,13 +5545,35 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
{
struct sctp_setprim *spa;
struct sctp_nets *net;
struct sockaddr *addr;
#if defined(INET) && defined(INET6)
struct sockaddr_in sin_store;
#endif
SCTP_CHECK_AND_CAST(spa, optval, struct sctp_setprim, optsize);
SCTP_FIND_STCB(inp, stcb, spa->ssp_assoc_id);
net = NULL;
if (stcb) {
net = sctp_findnet(stcb, (struct sockaddr *)&spa->ssp_addr);
#if defined(INET) && defined(INET6)
if (spa->ssp_addr.ss_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&spa->ssp_addr;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
in6_sin6_2_sin(&sin_store, sin6);
addr = (struct sockaddr *)&sin_store;
} else {
addr = (struct sockaddr *)&spa->ssp_addr;
}
} else {
addr = (struct sockaddr *)&spa->ssp_addr;
}
#else
addr = (struct sockaddr *)&spa->ssp_addr;
#endif
if (stcb != NULL) {
net = sctp_findnet(stcb, addr);
} else {
/*
* We increment here since
@ -5424,16 +5582,16 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
* the locked tcb (last argument) is NOT a
* TCB.. aka NULL.
*/
net = NULL;
SCTP_INP_INCR_REF(inp);
stcb = sctp_findassociation_ep_addr(&inp,
(struct sockaddr *)&spa->ssp_addr,
stcb = sctp_findassociation_ep_addr(&inp, addr,
&net, NULL, NULL);
if (stcb == NULL) {
SCTP_INP_DECR_REF(inp);
}
}
if ((stcb) && (net)) {
if ((stcb != NULL) && (net != NULL)) {
if ((net != stcb->asoc.primary_destination) &&
(!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) {
/* Ok we need to set it */
@ -5450,7 +5608,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
error = EINVAL;
}
if (stcb) {
if (stcb != NULL) {
SCTP_TCB_UNLOCK(stcb);
}
break;
@ -5472,14 +5630,36 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
case SCTP_SET_PEER_PRIMARY_ADDR:
{
struct sctp_setpeerprim *sspp;
struct sockaddr *addr;
#if defined(INET) && defined(INET6)
struct sockaddr_in sin_store;
#endif
SCTP_CHECK_AND_CAST(sspp, optval, struct sctp_setpeerprim, optsize);
SCTP_FIND_STCB(inp, stcb, sspp->sspp_assoc_id);
if (stcb != NULL) {
struct sctp_ifa *ifa;
ifa = sctp_find_ifa_by_addr((struct sockaddr *)&sspp->sspp_addr,
stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
#if defined(INET) && defined(INET6)
if (sspp->sspp_addr.ss_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&sspp->sspp_addr;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
in6_sin6_2_sin(&sin_store, sin6);
addr = (struct sockaddr *)&sin_store;
} else {
addr = (struct sockaddr *)&sspp->sspp_addr;
}
} else {
addr = (struct sockaddr *)&sspp->sspp_addr;
}
#else
addr = (struct sockaddr *)&sspp->sspp_addr;
#endif
ifa = sctp_find_ifa_by_addr(addr, stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
if (ifa == NULL) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
error = EINVAL;
@ -5510,13 +5690,13 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
goto out_of_it;
}
} else {
switch (sspp->sspp_addr.ss_family) {
switch (addr->sa_family) {
#ifdef INET
case AF_INET:
{
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)&sspp->sspp_addr;
sin = (struct sockaddr_in *)addr;
if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
&sin->sin_addr) != 0) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
@ -5531,7 +5711,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
{
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&sspp->sspp_addr;
sin6 = (struct sockaddr_in6 *)addr;
if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
&sin6->sin6_addr) != 0) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
@ -5547,8 +5727,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
goto out_of_it;
}
}
if (sctp_set_primary_ip_address_sa(stcb,
(struct sockaddr *)&sspp->sspp_addr) != 0) {
if (sctp_set_primary_ip_address_sa(stcb, addr) != 0) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
error = EINVAL;
}
@ -5899,12 +6078,35 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
{
struct sctp_paddrthlds *thlds;
struct sctp_nets *net;
struct sockaddr *addr;
#if defined(INET) && defined(INET6)
struct sockaddr_in sin_store;
#endif
SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, optsize);
SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
net = NULL;
if (stcb) {
net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address);
#if defined(INET) && defined(INET6)
if (thlds->spt_address.ss_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&thlds->spt_address;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
in6_sin6_2_sin(&sin_store, sin6);
addr = (struct sockaddr *)&sin_store;
} else {
addr = (struct sockaddr *)&thlds->spt_address;
}
} else {
addr = (struct sockaddr *)&thlds->spt_address;
}
#else
addr = (struct sockaddr *)&thlds->spt_address;
#endif
if (stcb != NULL) {
net = sctp_findnet(stcb, addr);
} else {
/*
* We increment here since
@ -5913,25 +6115,22 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
* the locked tcb (last argument) is NOT a
* TCB.. aka NULL.
*/
net = NULL;
SCTP_INP_INCR_REF(inp);
stcb = sctp_findassociation_ep_addr(&inp,
(struct sockaddr *)&thlds->spt_address,
stcb = sctp_findassociation_ep_addr(&inp, addr,
&net, NULL, NULL);
if (stcb == NULL) {
SCTP_INP_DECR_REF(inp);
}
}
if (stcb && (net == NULL)) {
struct sockaddr *sa;
sa = (struct sockaddr *)&thlds->spt_address;
if ((stcb != NULL) && (net == NULL)) {
#ifdef INET
if (sa->sa_family == AF_INET) {
if (addr->sa_family == AF_INET) {
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)sa;
if (sin->sin_addr.s_addr) {
sin = (struct sockaddr_in *)addr;
if (sin->sin_addr.s_addr != INADDR_ANY) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
SCTP_TCB_UNLOCK(stcb);
error = EINVAL;
@ -5940,10 +6139,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
} else
#endif
#ifdef INET6
if (sa->sa_family == AF_INET6) {
if (addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)sa;
sin6 = (struct sockaddr_in6 *)addr;
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
SCTP_TCB_UNLOCK(stcb);
@ -5959,8 +6158,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
break;
}
}
if (stcb) {
if (net) {
if (stcb != NULL) {
if (net != NULL) {
if (net->dest_state & SCTP_ADDR_PF) {
if ((net->failure_threshold > thlds->spt_pathmaxrxt) ||
(net->failure_threshold <= thlds->spt_pathpfthld)) {
@ -6040,11 +6239,35 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
{
struct sctp_udpencaps *encaps;
struct sctp_nets *net;
struct sockaddr *addr;
#if defined(INET) && defined(INET6)
struct sockaddr_in sin_store;
#endif
SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, optsize);
SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id);
if (stcb) {
net = sctp_findnet(stcb, (struct sockaddr *)&encaps->sue_address);
#if defined(INET) && defined(INET6)
if (encaps->sue_address.ss_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&encaps->sue_address;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
in6_sin6_2_sin(&sin_store, sin6);
addr = (struct sockaddr *)&sin_store;
} else {
addr = (struct sockaddr *)&encaps->sue_address;
}
} else {
addr = (struct sockaddr *)&encaps->sue_address;
}
#else
addr = (struct sockaddr *)&encaps->sue_address;
#endif
if (stcb != NULL) {
net = sctp_findnet(stcb, addr);
} else {
/*
* We increment here since
@ -6055,22 +6278,19 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
*/
net = NULL;
SCTP_INP_INCR_REF(inp);
stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&encaps->sue_address, &net, NULL, NULL);
stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
if (stcb == NULL) {
SCTP_INP_DECR_REF(inp);
}
}
if (stcb && (net == NULL)) {
struct sockaddr *sa;
sa = (struct sockaddr *)&encaps->sue_address;
if ((stcb != NULL) && (net == NULL)) {
#ifdef INET
if (sa->sa_family == AF_INET) {
if (addr->sa_family == AF_INET) {
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)sa;
if (sin->sin_addr.s_addr) {
sin = (struct sockaddr_in *)addr;
if (sin->sin_addr.s_addr != INADDR_ANY) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
SCTP_TCB_UNLOCK(stcb);
error = EINVAL;
@ -6079,10 +6299,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
} else
#endif
#ifdef INET6
if (sa->sa_family == AF_INET6) {
if (addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)sa;
sin6 = (struct sockaddr_in6 *)addr;
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
SCTP_TCB_UNLOCK(stcb);
@ -6098,8 +6318,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
break;
}
}
if (stcb) {
if (net) {
if (stcb != NULL) {
if (net != NULL) {
net->port = encaps->sue_port;
} else {
stcb->asoc.port = encaps->sue_port;

View File

@ -2760,7 +2760,16 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
switch (sa->sa_family) {
#ifdef INET
case AF_INET:
#ifdef INET6
if (sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
in6_sin_2_v4mapsin6((struct sockaddr_in *)sa,
(struct sockaddr_in6 *)&spc->spc_aaddr);
} else {
memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
}
#else
memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
#endif
break;
#endif
#ifdef INET6
@ -5653,43 +5662,43 @@ sctp_sorecvmsg(struct socket *so,
entry->flgs = control->sinfo_flags;
}
#endif
if (fromlen && from) {
cp_len = min((size_t)fromlen, (size_t)control->whoFrom->ro._l_addr.sa.sa_len);
if ((fromlen > 0) && (from != NULL)) {
union sctp_sockstore store;
size_t len;
switch (control->whoFrom->ro._l_addr.sa.sa_family) {
#ifdef INET6
case AF_INET6:
((struct sockaddr_in6 *)from)->sin6_port = control->port_from;
len = sizeof(struct sockaddr_in6);
store.sin6 = control->whoFrom->ro._l_addr.sin6;
store.sin6.sin6_port = control->port_from;
break;
#endif
#ifdef INET
case AF_INET:
((struct sockaddr_in *)from)->sin_port = control->port_from;
#ifdef INET6
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
len = sizeof(struct sockaddr_in6);
in6_sin_2_v4mapsin6(&control->whoFrom->ro._l_addr.sin,
&store.sin6);
store.sin6.sin6_port = control->port_from;
} else {
len = sizeof(struct sockaddr_in);
store.sin = control->whoFrom->ro._l_addr.sin;
store.sin.sin_port = control->port_from;
}
#else
len = sizeof(struct sockaddr_in);
store.sin = control->whoFrom->ro._l_addr.sin;
store.sin.sin_port = control->port_from;
#endif
break;
#endif
default:
len = 0;
break;
}
memcpy(from, &control->whoFrom->ro._l_addr, cp_len);
#if defined(INET) && defined(INET6)
if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) &&
(from->sa_family == AF_INET) &&
((size_t)fromlen >= sizeof(struct sockaddr_in6))) {
struct sockaddr_in *sin;
struct sockaddr_in6 sin6;
sin = (struct sockaddr_in *)from;
bzero(&sin6, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_addr.s6_addr32[2] = htonl(0xffff);
bcopy(&sin->sin_addr,
&sin6.sin6_addr.s6_addr32[3],
sizeof(sin6.sin6_addr.s6_addr32[3]));
sin6.sin6_port = sin->sin_port;
memcpy(from, &sin6, sizeof(struct sockaddr_in6));
}
#endif
memcpy(from, &store, min((size_t)fromlen, len));
#ifdef INET6
{
struct sockaddr_in6 lsa6, *from6;
@ -6450,7 +6459,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
{
struct sockaddr *addr_touse;
#ifdef INET6
#if defined(INET) && defined(INET6)
struct sockaddr_in sin;
#endif
@ -6464,8 +6473,10 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
addr_touse = sa;
#ifdef INET6
if (sa->sa_family == AF_INET6) {
#ifdef INET
struct sockaddr_in6 *sin6;
#endif
if (sa->sa_len != sizeof(struct sockaddr_in6)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
@ -6477,6 +6488,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
*error = EINVAL;
return;
}
#ifdef INET
sin6 = (struct sockaddr_in6 *)addr_touse;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
@ -6489,6 +6501,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
in6_sin6_2_sin(&sin, sin6);
addr_touse = (struct sockaddr *)&sin;
}
#endif
}
#endif
#ifdef INET
@ -6578,7 +6591,7 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
{
struct sockaddr *addr_touse;
#ifdef INET6
#if defined(INET) && defined(INET6)
struct sockaddr_in sin;
#endif
@ -6592,8 +6605,11 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
addr_touse = sa;
#ifdef INET6
if (sa->sa_family == AF_INET6) {
#ifdef INET
struct sockaddr_in6 *sin6;
#endif
if (sa->sa_len != sizeof(struct sockaddr_in6)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
@ -6605,6 +6621,7 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
*error = EINVAL;
return;
}
#ifdef INET
sin6 = (struct sockaddr_in6 *)addr_touse;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
@ -6617,6 +6634,7 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
in6_sin6_2_sin(&sin, sin6);
addr_touse = (struct sockaddr *)&sin;
}
#endif
}
#endif
#ifdef INET

View File

@ -216,10 +216,10 @@ udp_init(void)
* a 4-tuple, flip this to 4-tuple.
*/
in_pcbinfo_init(&V_udbinfo, "udp", &V_udb, UDBHASHSIZE, UDBHASHSIZE,
"udp_inpcb", udp_inpcb_init, NULL, UMA_ZONE_NOFREE,
"udp_inpcb", udp_inpcb_init, NULL, 0,
IPI_HASHFIELDS_2TUPLE);
V_udpcb_zone = uma_zcreate("udpcb", sizeof(struct udpcb),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
uma_zone_set_max(V_udpcb_zone, maxsockets);
uma_zone_set_warning(V_udpcb_zone, "kern.ipc.maxsockets limit reached");
EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL,
@ -232,7 +232,7 @@ udplite_init(void)
in_pcbinfo_init(&V_ulitecbinfo, "udplite", &V_ulitecb, UDBHASHSIZE,
UDBHASHSIZE, "udplite_inpcb", udplite_inpcb_init, NULL,
UMA_ZONE_NOFREE, IPI_HASHFIELDS_2TUPLE);
0, IPI_HASHFIELDS_2TUPLE);
}
/*

View File

@ -2313,7 +2313,8 @@ key_spdacquire(struct secpolicy *sp)
} else {
/* increment counter and do nothing. */
newspacq->count++;
return 0;
SPACQ_UNLOCK();
return (0);
}
SPACQ_UNLOCK();
} else {

View File

@ -39,15 +39,6 @@ struct vattr;
struct vnode;
struct reg;
/*
* Cyclic clock function type definition used to hook the cyclic
* subsystem into the appropriate timer interrupt.
*/
typedef void (*cyclic_clock_func_t)(struct trapframe *);
extern cyclic_clock_func_t cyclic_clock_func;
void clocksource_cyc_set(const struct bintime *t);
int dtrace_trap(struct trapframe *);
/*

View File

@ -81,7 +81,6 @@
#define P_OSREL_SIGSEGV 700004
#define P_OSREL_MAP_ANON 800104
#define P_OSREL_MAP_FSTRICT 1100036
#define P_OSREL_MAP_RENAME 1100039
#define P_OSREL_MAJOR(x) ((x) / 100000)
#endif

View File

@ -222,8 +222,7 @@ sys_mmap(td, uap)
/*
* Ignore old flags that used to be defined but did not do anything.
*/
if (td->td_proc->p_osrel < P_OSREL_MAP_RENAME)
flags &= ~(MAP_RESERVED0020 | MAP_RESERVED0040);
flags &= ~(MAP_RESERVED0020 | MAP_RESERVED0040);
/*
* Enforce the constraints.

View File

@ -468,7 +468,12 @@ vm_object_vndeallocate(vm_object_t object)
}
#endif
if (object->ref_count > 1) {
/*
* The test for text of vp vnode does not need a bypass to
* reach right VV_TEXT there, since it is obtained from
* object->handle.
*/
if (object->ref_count > 1 || (vp->v_vflag & VV_TEXT) == 0) {
object->ref_count--;
VM_OBJECT_WUNLOCK(object);
/* vrele may need the vnode lock. */

View File

@ -4,7 +4,7 @@ PROG= iscsictl
SRCS= iscsictl.c periphs.c parse.y token.l y.tab.h
CFLAGS+= -I${.CURDIR}
CFLAGS+= -I${.CURDIR}/../../sys/dev/iscsi
MAN= iscsictl.8
MAN= iscsi.conf.5 iscsictl.8
LIBADD= cam util

View File

@ -23,7 +23,7 @@
* -C option added in 1998, original code by Marc Espie, based on FreeBSD
* behaviour
*
* $OpenBSD: patch.c,v 1.50 2012/05/15 19:32:02 millert Exp $
* $OpenBSD: patch.c,v 1.52 2014/11/26 18:34:51 millert Exp $
* $FreeBSD$
*
*/
@ -150,8 +150,8 @@ main(int argc, char *argv[])
const char *tmpdir;
char *v;
setlinebuf(stdout);
setlinebuf(stderr);
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(stderr, NULL, _IOLBF, 0);
for (i = 0; i < MAXFILEC; i++)
filearg[i] = NULL;

View File

@ -24,7 +24,7 @@
* -C option added in 1998, original code by Marc Espie, based on FreeBSD
* behaviour
*
* $OpenBSD: pch.c,v 1.39 2012/04/11 08:07:13 ajacoutot Exp $
* $OpenBSD: pch.c,v 1.43 2014/11/18 17:03:35 tobias Exp $
* $FreeBSD$
*/
@ -46,7 +46,7 @@
/* Patch (diff listing) abstract type. */
static long p_filesize; /* size of the patch file */
static off_t p_filesize; /* size of the patch file */
static LINENUM p_first; /* 1st line number */
static LINENUM p_newfirst; /* 1st line number of replacement */
static LINENUM p_ptrn_lines; /* # lines in pattern */
@ -60,9 +60,9 @@ static unsigned short *p_len = NULL; /* length of each line */
static char *p_char = NULL; /* +, -, and ! */
static int hunkmax = INITHUNKMAX; /* size of above arrays to begin with */
static int p_indent; /* indent to patch */
static LINENUM p_base; /* where to intuit this time */
static off_t p_base; /* where to intuit this time */
static LINENUM p_bline; /* line # of p_base */
static LINENUM p_start; /* where intuit found a patch */
static off_t p_start; /* where intuit found a patch */
static LINENUM p_sline; /* and the line number for it */
static LINENUM p_hunk_beg; /* line number of current hunk */
static LINENUM p_efake = -1; /* end of faked up lines--don't free */
@ -72,8 +72,8 @@ static char *bestguess = NULL; /* guess at correct filename */
static void grow_hunkmax(void);
static int intuit_diff_type(void);
static void next_intuit_at(LINENUM, LINENUM);
static void skip_to(LINENUM, LINENUM);
static void next_intuit_at(off_t, LINENUM);
static void skip_to(off_t, LINENUM);
static size_t pgets(bool _do_indent);
static char *best_name(const struct file_name *, bool);
static char *posix_name(const struct file_name *, bool);
@ -119,9 +119,10 @@ open_patch_file(const char *filename)
pfp = fopen(filename, "r");
if (pfp == NULL)
pfatal("patch file %s not found", filename);
fstat(fileno(pfp), &filestat);
if (fstat(fileno(pfp), &filestat))
pfatal("can't stat %s", filename);
p_filesize = filestat.st_size;
next_intuit_at(0L, 1L); /* start at the beginning */
next_intuit_at(0, 1L); /* start at the beginning */
set_hunkmax();
}
@ -172,7 +173,7 @@ there_is_another_patch(void)
{
bool exists = false;
if (p_base != 0L && p_base >= p_filesize) {
if (p_base != 0 && p_base >= p_filesize) {
if (verbose)
say("done\n");
return false;
@ -181,7 +182,7 @@ there_is_another_patch(void)
say("Hmm...");
diff_type = intuit_diff_type();
if (!diff_type) {
if (p_base != 0L) {
if (p_base != 0) {
if (verbose)
say(" Ignoring the trailing garbage.\ndone\n");
} else
@ -190,7 +191,7 @@ there_is_another_patch(void)
}
if (verbose)
say(" %sooks like %s to me...\n",
(p_base == 0L ? "L" : "The next patch l"),
(p_base == 0 ? "L" : "The next patch l"),
diff_type == UNI_DIFF ? "a unified diff" :
diff_type == CONTEXT_DIFF ? "a context diff" :
diff_type == NEW_CONTEXT_DIFF ? "a new-style context diff" :
@ -252,8 +253,8 @@ p4_fetchname(struct file_name *name, char *str)
static int
intuit_diff_type(void)
{
long this_line = 0, previous_line;
long first_command_line = -1;
off_t this_line = 0, previous_line;
off_t first_command_line = -1;
LINENUM fcl_line = -1;
bool last_line_was_command = false, this_is_a_command = false;
bool stars_last_line = false, stars_this_line = false;
@ -263,17 +264,17 @@ intuit_diff_type(void)
memset(names, 0, sizeof(names));
ok_to_create_file = false;
fseek(pfp, p_base, SEEK_SET);
fseeko(pfp, p_base, SEEK_SET);
p_input_line = p_bline - 1;
for (;;) {
previous_line = this_line;
last_line_was_command = this_is_a_command;
stars_last_line = stars_this_line;
this_line = ftell(pfp);
this_line = ftello(pfp);
indent = 0;
p_input_line++;
if (pgets(false) == 0) {
if (first_command_line >= 0L) {
if (first_command_line >= 0) {
/* nothing but deletes!? */
p_start = first_command_line;
p_sline = fcl_line;
@ -296,7 +297,7 @@ intuit_diff_type(void)
;
this_is_a_command = (isdigit((unsigned char)*s) &&
(*t == 'd' || *t == 'c' || *t == 'a'));
if (first_command_line < 0L && this_is_a_command) {
if (first_command_line < 0 && this_is_a_command) {
first_command_line = this_line;
fcl_line = p_input_line;
p_indent = indent; /* assume this for now */
@ -318,7 +319,8 @@ intuit_diff_type(void)
for (t = s + 7; isspace((unsigned char)*t); t++)
;
revision = savestr(t);
for (t = revision; *t && !isspace((unsigned char)*t); t++)
for (t = revision;
*t && !isspace((unsigned char)*t); t++)
;
*t = '\0';
if (*revision == '\0') {
@ -332,7 +334,7 @@ intuit_diff_type(void)
p4_fetchname(&names[OLD_FILE], s + 5);
}
if ((!diff_type || diff_type == ED_DIFF) &&
first_command_line >= 0L &&
first_command_line >= 0 &&
strEQ(s, ".\n")) {
p_indent = indent;
p_start = first_command_line;
@ -356,9 +358,9 @@ intuit_diff_type(void)
ok_to_create_file = true;
/*
* If this is a new context diff the character just
* before the newline is a '*'.
* at the end of the line is a '*'.
*/
while (*s != '\n')
while (*s && *s != '\n')
s++;
p_indent = indent;
p_start = previous_line;
@ -422,26 +424,27 @@ intuit_diff_type(void)
* Remember where this patch ends so we know where to start up again.
*/
static void
next_intuit_at(LINENUM file_pos, LINENUM file_line)
next_intuit_at(off_t file_pos, LINENUM file_line)
{
p_base = file_pos;
p_bline = file_line;
}
/*
* Basically a verbose fseek() to the actual diff listing.
* Basically a verbose fseeko() to the actual diff listing.
*/
static void
skip_to(LINENUM file_pos, LINENUM file_line)
skip_to(off_t file_pos, LINENUM file_line)
{
size_t len;
if (p_base > file_pos)
fatal("Internal error: seek %ld>%ld\n", p_base, file_pos);
fatal("Internal error: seek %lld>%lld\n",
(long long)p_base, (long long)file_pos);
if (verbose && p_base < file_pos) {
fseek(pfp, p_base, SEEK_SET);
fseeko(pfp, p_base, SEEK_SET);
say("The text leading up to this was:\n--------------------------\n");
while (ftell(pfp) < file_pos) {
while (ftello(pfp) < file_pos) {
len = pgets(false);
if (len == 0)
fatal("Unexpected end of file\n");
@ -449,7 +452,7 @@ skip_to(LINENUM file_pos, LINENUM file_line)
}
say("--------------------------\n");
} else
fseek(pfp, file_pos, SEEK_SET);
fseeko(pfp, file_pos, SEEK_SET);
p_input_line = file_line - 1;
}
@ -479,7 +482,7 @@ remove_special_line(void)
return true;
}
if (c != EOF)
fseek(pfp, -1L, SEEK_CUR);
fseeko(pfp, -1, SEEK_CUR);
return false;
}
@ -490,7 +493,7 @@ remove_special_line(void)
bool
another_hunk(void)
{
long line_beginning; /* file pos of the current line */
off_t line_beginning; /* file pos of the current line */
LINENUM repl_beginning; /* index of --- line */
LINENUM fillcnt; /* #lines of missing ptrn or repl */
LINENUM fillsrc; /* index of first line to copy */
@ -498,7 +501,7 @@ another_hunk(void)
bool ptrn_spaces_eaten; /* ptrn was slightly misformed */
bool repl_could_be_missing; /* no + or ! lines in this hunk */
bool repl_missing; /* we are now backtracking */
long repl_backtrack_position; /* file pos of first repl line */
off_t repl_backtrack_position; /* file pos of first repl line */
LINENUM repl_patch_line; /* input line number for same */
LINENUM ptrn_copiable; /* # of copiable lines in ptrn */
char *s;
@ -516,7 +519,7 @@ another_hunk(void)
p_max = hunkmax; /* gets reduced when --- found */
if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) {
line_beginning = ftell(pfp);
line_beginning = ftello(pfp);
repl_beginning = 0;
fillcnt = 0;
fillsrc = 0;
@ -537,7 +540,7 @@ another_hunk(void)
p_context = 100;
p_hunk_beg = p_input_line + 1;
while (p_end < p_max) {
line_beginning = ftell(pfp);
line_beginning = ftello(pfp);
len = pgets(true);
p_input_line++;
if (len == 0) {
@ -583,7 +586,8 @@ another_hunk(void)
p_end--;
return false;
}
for (s = buf; *s && !isdigit((unsigned char)*s); s++)
for (s = buf;
*s && !isdigit((unsigned char)*s); s++)
;
if (!*s)
malformed();
@ -593,7 +597,8 @@ another_hunk(void)
while (isdigit((unsigned char)*s))
s++;
if (*s == ',') {
for (; *s && !isdigit((unsigned char)*s); s++)
for (;
*s && !isdigit((unsigned char)*s); s++)
;
if (!*s)
malformed();
@ -644,7 +649,7 @@ another_hunk(void)
}
}
repl_beginning = p_end;
repl_backtrack_position = ftell(pfp);
repl_backtrack_position = ftello(pfp);
repl_patch_line = p_input_line;
p_line[p_end] = savestr(buf);
if (out_of_mem) {
@ -690,8 +695,8 @@ another_hunk(void)
change_line:
if (buf[1] == '\n' && canonicalize)
strlcpy(buf + 1, " \n", buf_size - 1);
if (!isspace((unsigned char)buf[1]) && buf[1] != '>' &&
buf[1] != '<' &&
if (!isspace((unsigned char)buf[1]) &&
buf[1] != '>' && buf[1] != '<' &&
repl_beginning && repl_could_be_missing) {
repl_missing = true;
goto hunk_done;
@ -776,7 +781,7 @@ another_hunk(void)
p_input_line = repl_patch_line;
for (p_end--; p_end > repl_beginning; p_end--)
free(p_line[p_end]);
fseek(pfp, repl_backtrack_position, SEEK_SET);
fseeko(pfp, repl_backtrack_position, SEEK_SET);
/* redundant 'new' context lines were omitted - set */
/* up to fill them in from the old file context */
@ -854,7 +859,7 @@ another_hunk(void)
LINENUM fillnew; /* index of new lines */
char ch;
line_beginning = ftell(pfp); /* file pos of the current line */
line_beginning = ftello(pfp); /* file pos of the current line */
len = pgets(true);
p_input_line++;
if (len == 0 || strnNE(buf, "@@ -", 4)) {
@ -918,7 +923,7 @@ another_hunk(void)
context = 0;
p_hunk_beg = p_input_line + 1;
while (fillold <= p_ptrn_lines || fillnew <= p_end) {
line_beginning = ftell(pfp);
line_beginning = ftello(pfp);
len = pgets(true);
p_input_line++;
if (len == 0) {
@ -1021,7 +1026,7 @@ another_hunk(void)
int i;
LINENUM min, max;
line_beginning = ftell(pfp);
line_beginning = ftello(pfp);
p_context = 0;
len = pgets(true);
p_input_line++;
@ -1398,7 +1403,7 @@ void
do_ed_script(void)
{
char *t;
long beginning_of_this_line;
off_t beginning_of_this_line;
FILE *pipefp = NULL;
if (!skip_rest_of_patch) {
@ -1411,7 +1416,7 @@ do_ed_script(void)
pipefp = popen(buf, "w");
}
for (;;) {
beginning_of_this_line = ftell(pfp);
beginning_of_this_line = ftello(pfp);
if (pgets(true) == 0) {
next_intuit_at(beginning_of_this_line, p_input_line);
break;
@ -1420,8 +1425,8 @@ do_ed_script(void)
for (t = buf; isdigit((unsigned char)*t) || *t == ','; t++)
;
/* POSIX defines allowed commands as {a,c,d,i,s} */
if (isdigit((unsigned char)*buf) && (*t == 'a' || *t == 'c' ||
*t == 'd' || *t == 'i' || *t == 's')) {
if (isdigit((unsigned char)*buf) &&
(*t == 'a' || *t == 'c' || *t == 'd' || *t == 'i' || *t == 's')) {
if (pipefp != NULL)
fputs(buf, pipefp);
if (*t != 'd') {

View File

@ -34,7 +34,7 @@
.\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
.\" $FreeBSD$
.\"
.Dd December 4, 2014
.Dd December 6, 2014
.Dt CTLADM 8
.Os
.Sh NAME
@ -995,6 +995,13 @@ command sequence order shall be explicitly handled by the application
client through the selection of appropriate commands and task attributes.
The default value is "restricted". It improves data integrity, but may
introduce some additional delays.
.It Va serseq
Set to "on" to serialize conseсutive reads/writes.
Set to "read" to serialize conseсutive reads.
Set to "off" to allow them be issued in parallel.
Parallel issue of consecutive operations may confuse logic of the
backing file system, hurting performance; but it may improve performance
of backing stores without prefetch/write-back.
.It Va rpm
Specifies medium rotation rate of the device: 0 -- not reported,
1 -- non-rotating (SSD), >1024 -- value in revolutions per minute.