MFhead @ r275589
This commit is contained in:
commit
2c3f939cab
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/building-blocks/; revision=275590
@ -68,6 +68,7 @@
|
|||||||
#ifdef sun
|
#ifdef sun
|
||||||
#include <aclutils.h>
|
#include <aclutils.h>
|
||||||
#include <directory.h>
|
#include <directory.h>
|
||||||
|
#include <idmap.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "zfs_iter.h"
|
#include "zfs_iter.h"
|
||||||
@ -2390,10 +2391,9 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space)
|
|||||||
/* SMB */
|
/* SMB */
|
||||||
char sid[ZFS_MAXNAMELEN + 32];
|
char sid[ZFS_MAXNAMELEN + 32];
|
||||||
uid_t id;
|
uid_t id;
|
||||||
uint64_t classes;
|
|
||||||
#ifdef sun
|
#ifdef sun
|
||||||
int err;
|
int err;
|
||||||
directory_error_t e;
|
int flag = IDMAP_REQ_FLG_USE_CACHE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
smbentity = B_TRUE;
|
smbentity = B_TRUE;
|
||||||
@ -2416,10 +2416,13 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space)
|
|||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
rid = id;
|
rid = id;
|
||||||
if (!cb->cb_sid2posix) {
|
if (!cb->cb_sid2posix) {
|
||||||
e = directory_name_from_sid(NULL, sid, &name,
|
if (type == USTYPE_SMB_USR) {
|
||||||
&classes);
|
(void) idmap_getwinnamebyuid(rid, flag,
|
||||||
if (e != NULL)
|
&name, NULL);
|
||||||
directory_error_free(e);
|
} else {
|
||||||
|
(void) idmap_getwinnamebygid(rid, flag,
|
||||||
|
&name, NULL);
|
||||||
|
}
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
name = sid;
|
name = sid;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LIBNVPAIR_H
|
#ifndef _LIBNVPAIR_H
|
||||||
@ -46,6 +47,7 @@ extern int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *,
|
|||||||
char **);
|
char **);
|
||||||
|
|
||||||
extern void nvlist_print(FILE *, nvlist_t *);
|
extern void nvlist_print(FILE *, nvlist_t *);
|
||||||
|
extern int nvlist_print_json(FILE *, nvlist_t *);
|
||||||
extern void dump_nvlist(nvlist_t *, int);
|
extern void dump_nvlist(nvlist_t *, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
403
cddl/contrib/opensolaris/lib/libnvpair/nvpair_json.c
Normal file
403
cddl/contrib/opensolaris/lib/libnvpair/nvpair_json.c
Normal 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);
|
||||||
|
}
|
@ -2615,7 +2615,7 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
|
|||||||
boolean_t isuser;
|
boolean_t isuser;
|
||||||
|
|
||||||
domain[0] = '\0';
|
domain[0] = '\0';
|
||||||
|
*ridp = 0;
|
||||||
/* Figure out the property type ({user|group}{quota|space}) */
|
/* Figure out the property type ({user|group}{quota|space}) */
|
||||||
for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) {
|
for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) {
|
||||||
if (strncmp(propname, zfs_userquota_prop_prefixes[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
|
* It's a SID name (eg "user@domain") that needs to be
|
||||||
* turned into S-1-domainID-RID.
|
* 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)
|
if (zoned && getzoneid() == GLOBAL_ZONEID)
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
if (isuser) {
|
if (isuser) {
|
||||||
e = directory_sid_from_user_name(NULL,
|
stat = idmap_getuidbywinname(cp, NULL, flag, &pid);
|
||||||
cp, &numericsid);
|
if (stat < 0)
|
||||||
|
return (ENOENT);
|
||||||
|
stat = idmap_get_sidbyuid(gh, pid, flag, &numericsid,
|
||||||
|
&rid, &map_stat);
|
||||||
} else {
|
} else {
|
||||||
e = directory_sid_from_group_name(NULL,
|
stat = idmap_getgidbywinname(cp, NULL, flag, &pid);
|
||||||
cp, &numericsid);
|
if (stat < 0)
|
||||||
|
return (ENOENT);
|
||||||
|
stat = idmap_get_sidbygid(gh, pid, flag, &numericsid,
|
||||||
|
&rid, &map_stat);
|
||||||
}
|
}
|
||||||
if (e != NULL) {
|
if (stat < 0) {
|
||||||
directory_error_free(e);
|
idmap_get_destroy(gh);
|
||||||
|
return (ENOENT);
|
||||||
|
}
|
||||||
|
stat = idmap_get_mappings(gh);
|
||||||
|
idmap_get_destroy(gh);
|
||||||
|
|
||||||
|
if (stat < 0) {
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
}
|
}
|
||||||
if (numericsid == NULL)
|
if (numericsid == NULL)
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
cp = numericsid;
|
cp = numericsid;
|
||||||
|
*ridp = rid;
|
||||||
/* will be further decoded below */
|
/* will be further decoded below */
|
||||||
#else /* !sun */
|
#else /* !sun */
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
@ -2663,12 +2686,15 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
|
|||||||
if (strncmp(cp, "S-1-", 4) == 0) {
|
if (strncmp(cp, "S-1-", 4) == 0) {
|
||||||
/* It's a numeric SID (eg "S-1-234-567-89") */
|
/* It's a numeric SID (eg "S-1-234-567-89") */
|
||||||
(void) strlcpy(domain, cp, domainlen);
|
(void) strlcpy(domain, cp, domainlen);
|
||||||
cp = strrchr(domain, '-');
|
|
||||||
*cp = '\0';
|
|
||||||
cp++;
|
|
||||||
|
|
||||||
errno = 0;
|
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) {
|
if (numericsid) {
|
||||||
free(numericsid);
|
free(numericsid);
|
||||||
numericsid = NULL;
|
numericsid = NULL;
|
||||||
|
@ -26,8 +26,6 @@
|
|||||||
#ifndef _CTFTOOLS_H
|
#ifndef _CTFTOOLS_H
|
||||||
#define _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
|
* Functions and data structures used in the manipulation of stabs and CTF data
|
||||||
*/
|
*/
|
||||||
@ -39,6 +37,8 @@
|
|||||||
#include <gelf.h>
|
#include <gelf.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <sys/ccompile.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -435,8 +435,8 @@ int streq(const char *, const char *);
|
|||||||
int findelfsecidx(Elf *, const char *, const char *);
|
int findelfsecidx(Elf *, const char *, const char *);
|
||||||
size_t elf_ptrsz(Elf *);
|
size_t elf_ptrsz(Elf *);
|
||||||
char *mktmpname(const char *, const char *);
|
char *mktmpname(const char *, const char *);
|
||||||
void terminate(const char *, ...);
|
void terminate(const char *, ...) __NORETURN;
|
||||||
void aborterr(const char *, ...);
|
void aborterr(const char *, ...) __NORETURN;
|
||||||
void set_terminate_cleanup(void (*)(void));
|
void set_terminate_cleanup(void (*)(void));
|
||||||
void elfterminate(const char *, const char *, ...);
|
void elfterminate(const char *, const char *, ...);
|
||||||
void warning(const char *, ...);
|
void warning(const char *, ...);
|
||||||
|
@ -9,6 +9,7 @@ SRCS= libnvpair.c \
|
|||||||
nvpair_alloc_system.c \
|
nvpair_alloc_system.c \
|
||||||
nvpair_alloc_fixed.c \
|
nvpair_alloc_fixed.c \
|
||||||
nvpair.c \
|
nvpair.c \
|
||||||
|
nvpair_json.c \
|
||||||
fnvpair.c
|
fnvpair.c
|
||||||
|
|
||||||
WARNS?= 0
|
WARNS?= 0
|
||||||
|
@ -6789,7 +6789,11 @@ do_co_reg (void)
|
|||||||
{
|
{
|
||||||
inst.instruction |= inst.operands[0].reg << 8;
|
inst.instruction |= inst.operands[0].reg << 8;
|
||||||
inst.instruction |= inst.operands[1].imm << 21;
|
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[3].reg << 16;
|
||||||
inst.instruction |= inst.operands[4].reg;
|
inst.instruction |= inst.operands[4].reg;
|
||||||
inst.instruction |= inst.operands[5].imm << 5;
|
inst.instruction |= inst.operands[5].imm << 5;
|
||||||
|
@ -115,7 +115,7 @@ __ieee754_j0(double x)
|
|||||||
if(ix<0x3f200000) { /* |x| < 2**-13 */
|
if(ix<0x3f200000) { /* |x| < 2**-13 */
|
||||||
if(huge+x>one) { /* raise inexact if x != 0 */
|
if(huge+x>one) { /* raise inexact if x != 0 */
|
||||||
if(ix<0x3e400000) return one; /* |x|<2**-27 */
|
if(ix<0x3e400000) return one; /* |x|<2**-27 */
|
||||||
else return one - 0.25*x*x;
|
else return one - x*x/4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
z = x*x;
|
z = x*x;
|
||||||
|
@ -69,10 +69,10 @@ __ieee754_j0f(float x)
|
|||||||
}
|
}
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
if(ix<0x39000000) { /* |x| < 2**-13 */
|
if(ix<0x3c000000) { /* |x| < 2**-7 */
|
||||||
if(huge+x>one) { /* raise inexact if x != 0 */
|
if(huge+x>one) { /* raise inexact if x != 0 */
|
||||||
if(ix<0x32000000) return one; /* |x|<2**-27 */
|
if(ix<0x39800000) return one; /* |x|<2**-12 */
|
||||||
else return one - (float)0.25*x*x;
|
else return one - x*x/4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
z = x*x;
|
z = x*x;
|
||||||
|
@ -8,6 +8,6 @@ S= ${.CURDIR}/../../sys
|
|||||||
WARNS?= 3
|
WARNS?= 3
|
||||||
CFLAGS+= -I$S
|
CFLAGS+= -I$S
|
||||||
|
|
||||||
MAN= iscsi.conf.5 iscontrol.8
|
MAN= iscontrol.8
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
@ -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"]
|
jpaetzel [label="Josh Paetzel\njpaetzel@FreeBSD.org\n2008/09/05"]
|
||||||
jsa [label="Joseph S. Atkinson\njsa@FreeBSD.org\n2010/07/15"]
|
jsa [label="Joseph S. Atkinson\njsa@FreeBSD.org\n2010/07/15"]
|
||||||
jylefort [label="Jean-Yves Lefort\njylefort@FreeBSD.org\n2005/04/12"]
|
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"]
|
kevlo [label="Kevin Lo\nkevlo@FreeBSD.org\n2003/02/21"]
|
||||||
kmoore [label="Kris Moore\nkmoore@FreeBSD.org\n2009/04/14"]
|
kmoore [label="Kris Moore\nkmoore@FreeBSD.org\n2009/04/14"]
|
||||||
knu [label="Akinori Musha\nknu@FreeBSD.org\n2000/03/22"]
|
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"]
|
romain [label="Romain Tartiere\nromain@FreeBSD.org\n2010/01/24"]
|
||||||
sahil [label="Sahil Tandon\nsahil@FreeBSD.org\n2010/04/11"]
|
sahil [label="Sahil Tandon\nsahil@FreeBSD.org\n2010/04/11"]
|
||||||
sat [label="Andrew Pantyukhin\nsat@FreeBSD.org\n2006/05/06"]
|
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"]
|
sbz [label="Sofian Brabez\nsbz@FreeBSD.org\n2011/03/14"]
|
||||||
scheidell [label="Michael Scheidell\nscheidell@FreeBSD.org\n2011/11/06"]
|
scheidell [label="Michael Scheidell\nscheidell@FreeBSD.org\n2011/11/06"]
|
||||||
sem [label="Sergey Matveychuk\nsem@FreeBSD.org\n2004/07/07"]
|
sem [label="Sergey Matveychuk\nsem@FreeBSD.org\n2004/07/07"]
|
||||||
@ -256,14 +258,17 @@ avilla -> jhale
|
|||||||
avilla -> rakuco
|
avilla -> rakuco
|
||||||
|
|
||||||
bdrewery -> dbn
|
bdrewery -> dbn
|
||||||
|
bdrewery -> sbruno
|
||||||
bdrewery -> trociny
|
bdrewery -> trociny
|
||||||
|
|
||||||
bapt -> bdrewery
|
bapt -> bdrewery
|
||||||
bapt -> eadler
|
bapt -> eadler
|
||||||
|
bapt -> grembo
|
||||||
bapt -> jlaffaye
|
bapt -> jlaffaye
|
||||||
bapt -> marius
|
bapt -> marius
|
||||||
bapt -> marino
|
bapt -> marino
|
||||||
bapt -> rodrigo
|
bapt -> rodrigo
|
||||||
|
bapt -> sbruno
|
||||||
|
|
||||||
beat -> decke
|
beat -> decke
|
||||||
beat -> marius
|
beat -> marius
|
||||||
@ -291,6 +296,8 @@ crees -> madpilot
|
|||||||
crees -> gblach
|
crees -> gblach
|
||||||
crees -> tijl
|
crees -> tijl
|
||||||
|
|
||||||
|
cs -> kami
|
||||||
|
|
||||||
culot -> danilo
|
culot -> danilo
|
||||||
culot -> jase
|
culot -> jase
|
||||||
culot -> marino
|
culot -> marino
|
||||||
@ -339,6 +346,7 @@ fjoe -> osa
|
|||||||
|
|
||||||
flo -> bar
|
flo -> bar
|
||||||
flo -> jase
|
flo -> jase
|
||||||
|
flo -> grembo
|
||||||
|
|
||||||
flz -> garga
|
flz -> garga
|
||||||
flz -> johans
|
flz -> johans
|
||||||
@ -389,6 +397,7 @@ knu -> maho
|
|||||||
knu -> nobutaka
|
knu -> nobutaka
|
||||||
knu -> nork
|
knu -> nork
|
||||||
|
|
||||||
|
koobs -> kami
|
||||||
koobs -> xmj
|
koobs -> xmj
|
||||||
|
|
||||||
krion -> brooks
|
krion -> brooks
|
||||||
|
@ -30,7 +30,7 @@ coresecretary [label="Core Team Secretary\ncore-secretary@FreeBSD.org\nmatthew"]
|
|||||||
doccommitters [label="Doc/www Committers\ndoc-committers@FreeBSD.org"]
|
doccommitters [label="Doc/www Committers\ndoc-committers@FreeBSD.org"]
|
||||||
doceng [label="Documentation Engineering Team\ndoceng@FreeBSD.org\ngjb, blackend,\ngabor, hrs"]
|
doceng [label="Documentation Engineering Team\ndoceng@FreeBSD.org\ngjb, blackend,\ngabor, hrs"]
|
||||||
portscommitters [label="Ports Committers\nports-committers@FreeBSD.org"]
|
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"]
|
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"]
|
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"]
|
secteam [label="Security Team\nsecteam@FreeBSD.org\nsimon, qingli, delphij,\nremko, philip, stas, cperciva,\ncsjp, rwatson, miwi, bz"]
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
.if !target(__<bsd.compiler.mk>__)
|
.if !target(__<bsd.compiler.mk>__)
|
||||||
__<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
|
_v!= ${CC} --version 2>/dev/null || echo 0.0.0
|
||||||
.if !defined(COMPILER_TYPE)
|
.if !defined(COMPILER_TYPE)
|
||||||
. if ${CC:T:M*gcc*}
|
. if ${CC:T:M*gcc*}
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
#include <machine/asm.h>
|
#include <machine/asm.h>
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
.cpu arm1136js
|
.cpu arm1176jz-s
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define Invalidate_I_cache(Rtmp1, Rtmp2) \
|
#define Invalidate_I_cache(Rtmp1, Rtmp2) \
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
#include "assym.s"
|
#include "assym.s"
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
#ifdef _ARM_ARCH_6
|
#ifdef _ARM_ARCH_6
|
||||||
#define GET_PCB(tmp) \
|
#define GET_PCB(tmp) \
|
||||||
mrc p15, 0, tmp, c13, c0, 4; \
|
mrc p15, 0, tmp, c13, c0, 4; \
|
||||||
@ -83,7 +85,7 @@ EENTRY_NP(casuword32)
|
|||||||
ldrt r5, [r0]
|
ldrt r5, [r0]
|
||||||
cmp r5, r1
|
cmp r5, r1
|
||||||
movne r0, r5
|
movne r0, r5
|
||||||
streqt r2, [r0]
|
strteq r2, [r0]
|
||||||
#endif
|
#endif
|
||||||
moveq r0, r1
|
moveq r0, r1
|
||||||
2:
|
2:
|
||||||
@ -269,7 +271,7 @@ _C_LABEL(fusubailout):
|
|||||||
|
|
||||||
fusupcbfaulttext:
|
fusupcbfaulttext:
|
||||||
.asciz "Yikes - no valid PCB during fusuxxx() addr=%08x\n"
|
.asciz "Yikes - no valid PCB during fusuxxx() addr=%08x\n"
|
||||||
.align 0
|
.align 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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_sub, "sub") \
|
||||||
EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_xor, "eor")
|
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(1, uint8_t, "ldrb", "strb", "streqb")
|
||||||
EMIT_ALL_OPS_N(2, uint16_t, "ldrh", "strh", "streqh")
|
EMIT_ALL_OPS_N(2, uint16_t, "ldrh", "strh", "streqh")
|
||||||
|
#endif
|
||||||
EMIT_ALL_OPS_N(4, uint32_t, "ldr", "str", "streq")
|
EMIT_ALL_OPS_N(4, uint32_t, "ldr", "str", "streq")
|
||||||
|
|
||||||
#ifndef __clang__
|
#ifndef __clang__
|
||||||
|
@ -1364,6 +1364,8 @@ ENTRY(memcpy)
|
|||||||
strbge r2, [r3], #0x01
|
strbge r2, [r3], #0x01
|
||||||
strbgt ip, [r3]
|
strbgt ip, [r3]
|
||||||
RET
|
RET
|
||||||
|
/* Place a literal pool here for the above ldr instructions to use */
|
||||||
|
.ltorg
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1171,7 +1171,7 @@ mv_pcib_alloc_msi(device_t dev, device_t child, int count,
|
|||||||
|
|
||||||
for (i = start; i < start + count; i++) {
|
for (i = start; i < start + count; i++) {
|
||||||
setbit(&sc->sc_msi_bitmap, 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);
|
debugf("%s: start: %x count: %x\n", __func__, start, count);
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include <machine/asm.h>
|
#include <machine/asm.h>
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
.arch armv7a
|
.cpu cortex-a8
|
||||||
.arch_extension sec
|
.arch_extension sec
|
||||||
|
|
||||||
/* Issue a smc #0 call */
|
/* Issue a smc #0 call */
|
||||||
|
@ -56,6 +56,7 @@ ENTRY(a4x_bs_r_1)
|
|||||||
ldr r0, [r1, r2, LSL #2]
|
ldr r0, [r1, r2, LSL #2]
|
||||||
and r0, r0, #0xff
|
and r0, r0, #0xff
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(a4x_bs_r_1)
|
||||||
|
|
||||||
ENTRY(a4x_bs_r_2)
|
ENTRY(a4x_bs_r_2)
|
||||||
ldr r0, [r1, r2, LSL #2]
|
ldr r0, [r1, r2, LSL #2]
|
||||||
@ -63,10 +64,12 @@ ENTRY(a4x_bs_r_2)
|
|||||||
orr r1, r1, r1, lsl #8
|
orr r1, r1, r1, lsl #8
|
||||||
and r0, r0, r1
|
and r0, r0, r1
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(a4x_bs_r_2)
|
||||||
|
|
||||||
ENTRY(a4x_bs_r_4)
|
ENTRY(a4x_bs_r_4)
|
||||||
ldr r0, [r1, r2, LSL #2]
|
ldr r0, [r1, r2, LSL #2]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(a4x_bs_r_4)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write single
|
* Write single
|
||||||
@ -75,6 +78,7 @@ ENTRY(a4x_bs_w_1)
|
|||||||
and r3, r3, #0xff
|
and r3, r3, #0xff
|
||||||
str r3, [r1, r2, LSL #2]
|
str r3, [r1, r2, LSL #2]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(a4x_bs_w_1)
|
||||||
|
|
||||||
ENTRY(a4x_bs_w_2)
|
ENTRY(a4x_bs_w_2)
|
||||||
mov r0, #0xff
|
mov r0, #0xff
|
||||||
@ -82,10 +86,12 @@ ENTRY(a4x_bs_w_2)
|
|||||||
and r3, r3, r0
|
and r3, r3, r0
|
||||||
str r3, [r1, r2, LSL #2]
|
str r3, [r1, r2, LSL #2]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(a4x_bs_w_2)
|
||||||
|
|
||||||
ENTRY(a4x_bs_w_4)
|
ENTRY(a4x_bs_w_4)
|
||||||
str r3, [r1, r2, LSL #2]
|
str r3, [r1, r2, LSL #2]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(a4x_bs_w_4)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read multiple
|
* Read multiple
|
||||||
@ -101,6 +107,7 @@ ENTRY(a4x_bs_rm_1)
|
|||||||
strb r3, [r1], #1
|
strb r3, [r1], #1
|
||||||
bne 1b
|
bne 1b
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(a4x_bs_rm_1)
|
||||||
|
|
||||||
ENTRY(a4x_bs_rm_2)
|
ENTRY(a4x_bs_rm_2)
|
||||||
add r0, r1, r2, lsl #2
|
add r0, r1, r2, lsl #2
|
||||||
@ -113,6 +120,7 @@ ENTRY(a4x_bs_rm_2)
|
|||||||
strh r3, [r1], #2
|
strh r3, [r1], #2
|
||||||
bne 1b
|
bne 1b
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(a4x_bs_rm_2)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write multiple
|
* Write multiple
|
||||||
@ -128,6 +136,7 @@ ENTRY(a4x_bs_wm_1)
|
|||||||
str r3, [r0]
|
str r3, [r0]
|
||||||
bne 1b
|
bne 1b
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(a4x_bs_wm_1)
|
||||||
|
|
||||||
ENTRY(a4x_bs_wm_2)
|
ENTRY(a4x_bs_wm_2)
|
||||||
add r0, r1, r2, lsl #2
|
add r0, r1, r2, lsl #2
|
||||||
@ -140,3 +149,4 @@ ENTRY(a4x_bs_wm_2)
|
|||||||
str r3, [r0]
|
str r3, [r0]
|
||||||
bne 1b
|
bne 1b
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(a4x_bs_wm_2)
|
||||||
|
@ -58,6 +58,7 @@ ENTRY(ixp425_pci_mem_bs_r_1)
|
|||||||
ldrb r0, [r1, r2]
|
ldrb r0, [r1, r2]
|
||||||
#endif /* __ARMEB__ */
|
#endif /* __ARMEB__ */
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(ixp425_pci_mem_bs_r_1)
|
||||||
|
|
||||||
ENTRY(ixp425_pci_mem_bs_r_2)
|
ENTRY(ixp425_pci_mem_bs_r_2)
|
||||||
#ifdef __ARMEB__
|
#ifdef __ARMEB__
|
||||||
@ -68,10 +69,12 @@ ENTRY(ixp425_pci_mem_bs_r_2)
|
|||||||
ldrh r0, [r1, r2]
|
ldrh r0, [r1, r2]
|
||||||
#endif /* __ARMEB__ */
|
#endif /* __ARMEB__ */
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(ixp425_pci_mem_bs_r_2)
|
||||||
|
|
||||||
ENTRY(ixp425_pci_mem_bs_r_4)
|
ENTRY(ixp425_pci_mem_bs_r_4)
|
||||||
ldr r0, [r1, r2]
|
ldr r0, [r1, r2]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(ixp425_pci_mem_bs_r_4)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* write single
|
* write single
|
||||||
@ -86,6 +89,7 @@ ENTRY(ixp425_pci_mem_bs_w_1)
|
|||||||
strb r3, [r1, r2]
|
strb r3, [r1, r2]
|
||||||
#endif /* __ARMEB__ */
|
#endif /* __ARMEB__ */
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(ixp425_pci_mem_bs_w_1)
|
||||||
|
|
||||||
ENTRY(ixp425_pci_mem_bs_w_2)
|
ENTRY(ixp425_pci_mem_bs_w_2)
|
||||||
#ifdef __ARMEB__
|
#ifdef __ARMEB__
|
||||||
@ -96,7 +100,9 @@ ENTRY(ixp425_pci_mem_bs_w_2)
|
|||||||
strh r3, [r1, r2]
|
strh r3, [r1, r2]
|
||||||
#endif /* __ARMEB__ */
|
#endif /* __ARMEB__ */
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(ixp425_pci_mem_bs_w_2)
|
||||||
|
|
||||||
ENTRY(ixp425_pci_mem_bs_w_4)
|
ENTRY(ixp425_pci_mem_bs_w_4)
|
||||||
str r3, [r1, r2]
|
str r3, [r1, r2]
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
END(ixp425_pci_mem_bs_w_4)
|
||||||
|
@ -109,6 +109,8 @@ SYSINIT_ENTRY(uniq##_entry, "sysuninit", (subs), \
|
|||||||
#define cold 0
|
#define cold 0
|
||||||
#define BUS_PROBE_GENERIC 0
|
#define BUS_PROBE_GENERIC 0
|
||||||
#define CALLOUT_RETURNUNLOCKED 0x1
|
#define CALLOUT_RETURNUNLOCKED 0x1
|
||||||
|
#undef ffs
|
||||||
|
#define ffs(x) __builtin_ffs(x)
|
||||||
#undef va_list
|
#undef va_list
|
||||||
#define va_list __builtin_va_list
|
#define va_list __builtin_va_list
|
||||||
#undef va_size
|
#undef va_size
|
||||||
|
@ -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_evpd(struct ctl_scsiio *ctsio);
|
||||||
static int ctl_inquiry_std(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 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,
|
static ctl_action ctl_check_for_blockage(struct ctl_lun *lun,
|
||||||
union ctl_io *pending_io, union ctl_io *ooa_io);
|
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,
|
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;
|
continue;
|
||||||
|
|
||||||
if (page_index->page_code == SLS_LOGICAL_BLOCK_PROVISIONING &&
|
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;
|
continue;
|
||||||
|
|
||||||
if (page_index->page_code != prev) {
|
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)
|
if (value != NULL && strcmp(value, "on") == 0)
|
||||||
lun->flags |= CTL_LUN_READONLY;
|
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;
|
lun->ctl_softc = ctl_softc;
|
||||||
TAILQ_INIT(&lun->ooa_queue);
|
TAILQ_INIT(&lun->ooa_queue);
|
||||||
TAILQ_INIT(&lun->blocked_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;
|
lbp_ptr->page_code = SVPD_LBP;
|
||||||
scsi_ulto2b(sizeof(*lbp_ptr) - 4, lbp_ptr->page_length);
|
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) {
|
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 |
|
lbp_ptr->flags = SVPD_LBP_UNMAP | SVPD_LBP_WS16 |
|
||||||
SVPD_LBP_WS10 | SVPD_LBP_RZ | SVPD_LBP_ANC_SUP;
|
SVPD_LBP_WS10 | SVPD_LBP_RZ | SVPD_LBP_ANC_SUP;
|
||||||
lbp_ptr->prov_type = SVPD_LBP_THIN;
|
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
|
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;
|
uint64_t endlba1, endlba2;
|
||||||
|
|
||||||
endlba1 = lba1 + len1 - 1;
|
endlba1 = lba1 + len1 - (seq ? 0 : 1);
|
||||||
endlba2 = lba2 + len2 - 1;
|
endlba2 = lba2 + len2 - 1;
|
||||||
|
|
||||||
if ((endlba1 < lba2)
|
if ((endlba1 < lba2) || (endlba2 < lba1))
|
||||||
|| (endlba2 < lba1))
|
|
||||||
return (CTL_ACTION_PASS);
|
return (CTL_ACTION_PASS);
|
||||||
else
|
else
|
||||||
return (CTL_ACTION_BLOCK);
|
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
|
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 lba1, lba2;
|
||||||
uint64_t len1, len2;
|
uint64_t len1, len2;
|
||||||
int retval;
|
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)
|
if (ctl_get_lba_len(io2, &lba2, &len2) != 0)
|
||||||
return (CTL_ACTION_ERROR);
|
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
|
static ctl_action
|
||||||
@ -10905,12 +10933,18 @@ ctl_check_for_blockage(struct ctl_lun *lun, union ctl_io *pending_io,
|
|||||||
case CTL_SER_BLOCK:
|
case CTL_SER_BLOCK:
|
||||||
return (CTL_ACTION_BLOCK);
|
return (CTL_ACTION_BLOCK);
|
||||||
case CTL_SER_EXTENT:
|
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:
|
case CTL_SER_EXTENTOPT:
|
||||||
if ((lun->mode_pages.control_page[CTL_PAGE_CURRENT].queue_flags
|
if ((lun->mode_pages.control_page[CTL_PAGE_CURRENT].queue_flags
|
||||||
& SCP_QUEUE_ALG_MASK) != SCP_QUEUE_ALG_UNRESTRICTED)
|
& SCP_QUEUE_ALG_MASK) != SCP_QUEUE_ALG_UNRESTRICTED)
|
||||||
return (ctl_extent_check(pending_io, ooa_io));
|
return (ctl_extent_check(ooa_io, pending_io,
|
||||||
/* FALLTHROUGH */
|
(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:
|
case CTL_SER_PASS:
|
||||||
return (CTL_ACTION_PASS);
|
return (CTL_ACTION_PASS);
|
||||||
case CTL_SER_BLOCKOPT:
|
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);
|
return (CTL_LUN_PAT_NONE);
|
||||||
|
|
||||||
action = ctl_extent_check_lba(lba1, len1, desc->lba_range.lba,
|
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
|
* A "pass" means that the LBA ranges don't overlap, so
|
||||||
* this doesn't match the user's range criteria.
|
* this doesn't match the user's range criteria.
|
||||||
@ -14002,7 +14036,6 @@ ctl_thresh_thread(void *arg)
|
|||||||
be_lun = lun->be_lun;
|
be_lun = lun->be_lun;
|
||||||
if ((lun->flags & CTL_LUN_DISABLED) ||
|
if ((lun->flags & CTL_LUN_DISABLED) ||
|
||||||
(lun->flags & CTL_LUN_OFFLINE) ||
|
(lun->flags & CTL_LUN_OFFLINE) ||
|
||||||
(be_lun->flags & CTL_LUN_FLAG_UNMAP) == 0 ||
|
|
||||||
lun->backend->lun_attr == NULL)
|
lun->backend->lun_attr == NULL)
|
||||||
continue;
|
continue;
|
||||||
rwpage = &lun->mode_pages.rw_er_page[CTL_PAGE_CURRENT];
|
rwpage = &lun->mode_pages.rw_er_page[CTL_PAGE_CURRENT];
|
||||||
|
@ -85,7 +85,8 @@ typedef enum {
|
|||||||
CTL_LUN_FLAG_DEVID = 0x20,
|
CTL_LUN_FLAG_DEVID = 0x20,
|
||||||
CTL_LUN_FLAG_DEV_TYPE = 0x40,
|
CTL_LUN_FLAG_DEV_TYPE = 0x40,
|
||||||
CTL_LUN_FLAG_UNMAP = 0x80,
|
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;
|
} ctl_backend_lun_flags;
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
|
@ -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;
|
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_OFFLINE;
|
||||||
if (unmap)
|
if (unmap)
|
||||||
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_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.be_lun = be_lun;
|
||||||
be_lun->ctl_be_lun.maxlba = (be_lun->size_blocks == 0) ?
|
be_lun->ctl_be_lun.maxlba = (be_lun->size_blocks == 0) ?
|
||||||
0 : (be_lun->size_blocks - 1);
|
0 : (be_lun->size_blocks - 1);
|
||||||
|
@ -97,6 +97,7 @@ typedef enum {
|
|||||||
CTL_SER_BLOCKOPT,
|
CTL_SER_BLOCKOPT,
|
||||||
CTL_SER_EXTENT,
|
CTL_SER_EXTENT,
|
||||||
CTL_SER_EXTENTOPT,
|
CTL_SER_EXTENTOPT,
|
||||||
|
CTL_SER_EXTENTSEQ,
|
||||||
CTL_SER_PASS,
|
CTL_SER_PASS,
|
||||||
CTL_SER_SKIP
|
CTL_SER_SKIP
|
||||||
} ctl_serialize_action;
|
} ctl_serialize_action;
|
||||||
@ -182,6 +183,12 @@ typedef enum {
|
|||||||
CTL_LUN_READONLY = 0x800
|
CTL_LUN_READONLY = 0x800
|
||||||
} ctl_lun_flags;
|
} ctl_lun_flags;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CTL_LUN_SERSEQ_OFF,
|
||||||
|
CTL_LUN_SERSEQ_READ,
|
||||||
|
CTL_LUN_SERSEQ_ON
|
||||||
|
} ctl_lun_serseq;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CTLBLOCK_FLAG_NONE = 0x00,
|
CTLBLOCK_FLAG_NONE = 0x00,
|
||||||
CTLBLOCK_FLAG_INVALID = 0x01
|
CTLBLOCK_FLAG_INVALID = 0x01
|
||||||
@ -386,6 +393,7 @@ struct ctl_lun {
|
|||||||
struct ctl_id target;
|
struct ctl_id target;
|
||||||
uint64_t lun;
|
uint64_t lun;
|
||||||
ctl_lun_flags flags;
|
ctl_lun_flags flags;
|
||||||
|
ctl_lun_serseq serseq;
|
||||||
STAILQ_HEAD(,ctl_error_desc) error_list;
|
STAILQ_HEAD(,ctl_error_desc) error_list;
|
||||||
uint64_t error_serial;
|
uint64_t error_serial;
|
||||||
struct ctl_softc *ctl_softc;
|
struct ctl_softc *ctl_softc;
|
||||||
|
@ -59,12 +59,13 @@
|
|||||||
#define bO CTL_SER_BLOCKOPT /* Optional block */
|
#define bO CTL_SER_BLOCKOPT /* Optional block */
|
||||||
#define xT CTL_SER_EXTENT /* Extent check */
|
#define xT CTL_SER_EXTENT /* Extent check */
|
||||||
#define xO CTL_SER_EXTENTOPT /* Optional extent check */
|
#define xO CTL_SER_EXTENTOPT /* Optional extent check */
|
||||||
|
#define xS CTL_SER_EXTENTSEQ /* Sequential extent check */
|
||||||
|
|
||||||
static ctl_serialize_action
|
static ctl_serialize_action
|
||||||
ctl_serialize_table[CTL_SERIDX_COUNT][CTL_SERIDX_COUNT] = {
|
ctl_serialize_table[CTL_SERIDX_COUNT][CTL_SERIDX_COUNT] = {
|
||||||
/**>IDX_ :: 2nd:TUR RD WRT UNM MDSN MDSL RQSN INQ RDCP RES LSNS FMT STR*/
|
/**>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},
|
/*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},
|
/*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},
|
/*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},
|
/*MD_SNS */{ bK, bK, bK, bK, pS, bK, bK, pS, pS, bK, pS, bK, bK},
|
||||||
|
@ -38,11 +38,8 @@ struct cyc_cpu;
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int cpuid;
|
int cpuid;
|
||||||
struct cyc_cpu *cpu_cyclic;
|
|
||||||
uint32_t cpu_flags;
|
uint32_t cpu_flags;
|
||||||
uint_t cpu_intr_actv;
|
uint_t cpu_intr_actv;
|
||||||
uintptr_t cpu_profile_pc;
|
|
||||||
uintptr_t cpu_profile_upc;
|
|
||||||
uintptr_t cpu_dtrace_caller; /* DTrace: caller, if any */
|
uintptr_t cpu_dtrace_caller; /* DTrace: caller, if any */
|
||||||
hrtime_t cpu_dtrace_chillmark; /* DTrace: chill mark time */
|
hrtime_t cpu_dtrace_chillmark; /* DTrace: chill mark time */
|
||||||
hrtime_t cpu_dtrace_chilled; /* DTrace: total chill time */
|
hrtime_t cpu_dtrace_chilled; /* DTrace: total chill time */
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -176,7 +176,7 @@ dtrace_optval_t dtrace_ustackframes_default = 20;
|
|||||||
dtrace_optval_t dtrace_jstackframes_default = 50;
|
dtrace_optval_t dtrace_jstackframes_default = 50;
|
||||||
dtrace_optval_t dtrace_jstackstrsize_default = 512;
|
dtrace_optval_t dtrace_jstackstrsize_default = 512;
|
||||||
int dtrace_msgdsize_max = 128;
|
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 */
|
hrtime_t dtrace_chill_interval = NANOSEC; /* 1000 ms */
|
||||||
int dtrace_devdepth_max = 32;
|
int dtrace_devdepth_max = 32;
|
||||||
int dtrace_err_verbose;
|
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))
|
if (!(sec->dofs_flags & DOF_SECF_LOAD))
|
||||||
continue; /* just ignore non-loadable sections */
|
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");
|
dtrace_dof_error(dof, "bad section alignment");
|
||||||
return (-1);
|
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);
|
DEV_MODULE(dtrace, dtrace_modevent, NULL);
|
||||||
MODULE_VERSION(dtrace, 1);
|
MODULE_VERSION(dtrace, 1);
|
||||||
MODULE_DEPEND(dtrace, cyclic, 1, 1, 1);
|
|
||||||
MODULE_DEPEND(dtrace, opensolaris, 1, 1, 1);
|
MODULE_DEPEND(dtrace, opensolaris, 1, 1, 1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2483,7 +2483,7 @@ fasttrap_load(void)
|
|||||||
if (nent == 0 || nent > 0x1000000)
|
if (nent == 0 || nent > 0x1000000)
|
||||||
nent = FASTTRAP_TPOINTS_DEFAULT_SIZE;
|
nent = FASTTRAP_TPOINTS_DEFAULT_SIZE;
|
||||||
|
|
||||||
if ((nent & (nent - 1)) == 0)
|
if (ISP2(nent))
|
||||||
fasttrap_tpoints.fth_nent = nent;
|
fasttrap_tpoints.fth_nent = nent;
|
||||||
else
|
else
|
||||||
fasttrap_tpoints.fth_nent = 1 << fasttrap_highbit(nent);
|
fasttrap_tpoints.fth_nent = 1 << fasttrap_highbit(nent);
|
||||||
@ -2501,7 +2501,7 @@ fasttrap_load(void)
|
|||||||
* ... and the providers hash table...
|
* ... and the providers hash table...
|
||||||
*/
|
*/
|
||||||
nent = FASTTRAP_PROVIDERS_DEFAULT_SIZE;
|
nent = FASTTRAP_PROVIDERS_DEFAULT_SIZE;
|
||||||
if ((nent & (nent - 1)) == 0)
|
if (ISP2(nent))
|
||||||
fasttrap_provs.fth_nent = nent;
|
fasttrap_provs.fth_nent = nent;
|
||||||
else
|
else
|
||||||
fasttrap_provs.fth_nent = 1 << fasttrap_highbit(nent);
|
fasttrap_provs.fth_nent = 1 << fasttrap_highbit(nent);
|
||||||
@ -2537,7 +2537,7 @@ fasttrap_load(void)
|
|||||||
* ... and the procs hash table.
|
* ... and the procs hash table.
|
||||||
*/
|
*/
|
||||||
nent = FASTTRAP_PROCS_DEFAULT_SIZE;
|
nent = FASTTRAP_PROCS_DEFAULT_SIZE;
|
||||||
if ((nent & (nent - 1)) == 0)
|
if (ISP2(nent))
|
||||||
fasttrap_procs.fth_nent = nent;
|
fasttrap_procs.fth_nent = nent;
|
||||||
else
|
else
|
||||||
fasttrap_procs.fth_nent = 1 << fasttrap_highbit(nent);
|
fasttrap_procs.fth_nent = 1 << fasttrap_highbit(nent);
|
||||||
|
@ -409,11 +409,11 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
|
|||||||
offsetof(dmu_sendarg_t, dsa_link));
|
offsetof(dmu_sendarg_t, dsa_link));
|
||||||
|
|
||||||
if (doi.doi_type == DMU_OTN_ZAP_METADATA) {
|
if (doi.doi_type == DMU_OTN_ZAP_METADATA) {
|
||||||
err = zap_contains(mos, dsobj, DS_FIELD_LARGE_BLOCKS);
|
int zaperr = zap_contains(mos, dsobj, DS_FIELD_LARGE_BLOCKS);
|
||||||
if (err == 0)
|
if (zaperr != ENOENT) {
|
||||||
|
VERIFY0(zaperr);
|
||||||
ds->ds_large_blocks = B_TRUE;
|
ds->ds_large_blocks = B_TRUE;
|
||||||
else
|
}
|
||||||
ASSERT3U(err, ==, ENOENT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
|
@ -1483,7 +1483,7 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
|
|||||||
}
|
}
|
||||||
if (scn->scn_visited_this_txg) {
|
if (scn->scn_visited_this_txg) {
|
||||||
zfs_dbgmsg("freed %llu blocks in %llums from "
|
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)scn->scn_visited_this_txg,
|
||||||
(longlong_t)
|
(longlong_t)
|
||||||
NSEC2MSEC(gethrtime() - scn->scn_sync_start_time),
|
NSEC2MSEC(gethrtime() - scn->scn_sync_start_time),
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
* Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
|
* Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
#include <sys/zfs_context.h>
|
#include <sys/zfs_context.h>
|
||||||
#include <sys/fm/fs/zfs.h>
|
#include <sys/fm/fs/zfs.h>
|
||||||
#include <sys/spa.h>
|
#include <sys/spa.h>
|
||||||
@ -151,7 +152,7 @@ zio_init(void)
|
|||||||
size_t align = 0;
|
size_t align = 0;
|
||||||
size_t cflags = (size > zio_buf_debug_limit) ? KMC_NODEBUG : 0;
|
size_t cflags = (size > zio_buf_debug_limit) ? KMC_NODEBUG : 0;
|
||||||
|
|
||||||
while (p2 & (p2 - 1))
|
while (!ISP2(p2))
|
||||||
p2 &= p2 - 1;
|
p2 &= p2 - 1;
|
||||||
|
|
||||||
#ifdef illumos
|
#ifdef illumos
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright 2014 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_CPUVAR_H
|
#ifndef _SYS_CPUVAR_H
|
||||||
@ -31,6 +32,7 @@
|
|||||||
#include <sys/disp.h>
|
#include <sys/disp.h>
|
||||||
#include <sys/processor.h>
|
#include <sys/processor.h>
|
||||||
|
|
||||||
|
#include <sys/loadavg.h>
|
||||||
#if (defined(_KERNEL) || defined(_KMEMUSER)) && defined(_MACHDEP)
|
#if (defined(_KERNEL) || defined(_KMEMUSER)) && defined(_MACHDEP)
|
||||||
#include <sys/machcpuvar.h>
|
#include <sys/machcpuvar.h>
|
||||||
#endif
|
#endif
|
||||||
@ -52,15 +54,6 @@ extern "C" {
|
|||||||
struct squeue_set_s;
|
struct squeue_set_s;
|
||||||
|
|
||||||
#define CPU_CACHE_COHERENCE_SIZE 64
|
#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.
|
* 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 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);
|
void start_cpus(void);
|
||||||
int cpus_paused(void);
|
int cpus_paused(void);
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ extern "C" {
|
|||||||
#if defined(sun)
|
#if defined(sun)
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#else
|
#else
|
||||||
|
#include <sys/cpuvar.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/linker.h>
|
#include <sys/linker.h>
|
||||||
#include <sys/ioccom.h>
|
#include <sys/ioccom.h>
|
||||||
@ -64,8 +65,8 @@ extern "C" {
|
|||||||
typedef int model_t;
|
typedef int model_t;
|
||||||
#endif
|
#endif
|
||||||
#include <sys/ctf_api.h>
|
#include <sys/ctf_api.h>
|
||||||
#include <sys/cyclic.h>
|
|
||||||
#if defined(sun)
|
#if defined(sun)
|
||||||
|
#include <sys/cyclic.h>
|
||||||
#include <sys/int_limits.h>
|
#include <sys/int_limits.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/stdint.h>
|
#include <sys/stdint.h>
|
||||||
|
@ -377,7 +377,9 @@ extern "C" {
|
|||||||
/*
|
/*
|
||||||
* Define the appropriate "implementation choices".
|
* Define the appropriate "implementation choices".
|
||||||
*/
|
*/
|
||||||
|
#if !defined(_ILP32)
|
||||||
#define _ILP32
|
#define _ILP32
|
||||||
|
#endif
|
||||||
#if !defined(_I32LPx) && defined(_KERNEL)
|
#if !defined(_I32LPx) && defined(_KERNEL)
|
||||||
#define _I32LPx
|
#define _I32LPx
|
||||||
#endif
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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);
|
|
@ -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);
|
|
||||||
}
|
|
@ -144,13 +144,6 @@ fbt_provide_module(void *arg, modctl_t *lf)
|
|||||||
if (strcmp(modname, "dtrace") == 0)
|
if (strcmp(modname, "dtrace") == 0)
|
||||||
return;
|
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
|
* To register with DTrace, a module must list 'dtrace' as a
|
||||||
* dependency in order for the kernel linker to resolve
|
* dependency in order for the kernel linker to resolve
|
||||||
|
@ -52,9 +52,9 @@
|
|||||||
#include <sys/smp.h>
|
#include <sys/smp.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
|
#include <machine/cpu.h>
|
||||||
#include <machine/stdarg.h>
|
#include <machine/stdarg.h>
|
||||||
|
|
||||||
#include <sys/cyclic.h>
|
|
||||||
#include <sys/dtrace.h>
|
#include <sys/dtrace.h>
|
||||||
#include <sys/dtrace_bsd.h>
|
#include <sys/dtrace_bsd.h>
|
||||||
|
|
||||||
@ -97,7 +97,7 @@
|
|||||||
* allow for a manual override in case we get it completely wrong.
|
* allow for a manual override in case we get it completely wrong.
|
||||||
*/
|
*/
|
||||||
#ifdef __amd64
|
#ifdef __amd64
|
||||||
#define PROF_ARTIFICIAL_FRAMES 7
|
#define PROF_ARTIFICIAL_FRAMES 10
|
||||||
#else
|
#else
|
||||||
#ifdef __i386
|
#ifdef __i386
|
||||||
#define PROF_ARTIFICIAL_FRAMES 6
|
#define PROF_ARTIFICIAL_FRAMES 6
|
||||||
@ -126,18 +126,30 @@
|
|||||||
#define PROF_ARTIFICIAL_FRAMES 3
|
#define PROF_ARTIFICIAL_FRAMES 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct profile_probe_percpu;
|
||||||
|
|
||||||
typedef struct profile_probe {
|
typedef struct profile_probe {
|
||||||
char prof_name[PROF_NAMELEN];
|
char prof_name[PROF_NAMELEN];
|
||||||
dtrace_id_t prof_id;
|
dtrace_id_t prof_id;
|
||||||
int prof_kind;
|
int prof_kind;
|
||||||
|
#ifdef illumos
|
||||||
hrtime_t prof_interval;
|
hrtime_t prof_interval;
|
||||||
cyclic_id_t prof_cyclic;
|
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;
|
} profile_probe_t;
|
||||||
|
|
||||||
typedef struct profile_probe_percpu {
|
typedef struct profile_probe_percpu {
|
||||||
hrtime_t profc_expected;
|
hrtime_t profc_expected;
|
||||||
hrtime_t profc_interval;
|
hrtime_t profc_interval;
|
||||||
profile_probe_t *profc_probe;
|
profile_probe_t *profc_probe;
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
struct callout profc_cyclic;
|
||||||
|
#endif
|
||||||
} profile_probe_percpu_t;
|
} profile_probe_percpu_t;
|
||||||
|
|
||||||
static d_open_t profile_open;
|
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 hrtime_t profile_interval_min = NANOSEC / 5000; /* 5000 hz */
|
||||||
static int profile_aframes = 0; /* override */
|
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
|
static void
|
||||||
profile_fire(void *arg)
|
profile_fire(void *arg)
|
||||||
{
|
{
|
||||||
profile_probe_percpu_t *pcpu = arg;
|
profile_probe_percpu_t *pcpu = arg;
|
||||||
profile_probe_t *prof = pcpu->profc_probe;
|
profile_probe_t *prof = pcpu->profc_probe;
|
||||||
hrtime_t late;
|
hrtime_t late;
|
||||||
solaris_cpu_t *c = &solaris_cpu[curcpu];
|
struct trapframe *frame;
|
||||||
|
uintfptr_t pc, upc;
|
||||||
|
|
||||||
|
#ifdef illumos
|
||||||
late = gethrtime() - pcpu->profc_expected;
|
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,
|
pc = 0;
|
||||||
c->cpu_profile_upc, late, 0, 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
|
static void
|
||||||
profile_tick(void *arg)
|
profile_tick(void *arg)
|
||||||
{
|
{
|
||||||
profile_probe_t *prof = 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,
|
pc = 0;
|
||||||
c->cpu_profile_upc, 0, 0, 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
|
static void
|
||||||
@ -250,8 +325,13 @@ profile_create(hrtime_t interval, char *name, int kind)
|
|||||||
|
|
||||||
prof = kmem_zalloc(sizeof (profile_probe_t), KM_SLEEP);
|
prof = kmem_zalloc(sizeof (profile_probe_t), KM_SLEEP);
|
||||||
(void) strcpy(prof->prof_name, name);
|
(void) strcpy(prof->prof_name, name);
|
||||||
|
#ifdef illumos
|
||||||
prof->prof_interval = interval;
|
prof->prof_interval = interval;
|
||||||
prof->prof_cyclic = CYCLIC_NONE;
|
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_kind = kind;
|
||||||
prof->prof_id = dtrace_probe_create(profile_id,
|
prof->prof_id = dtrace_probe_create(profile_id,
|
||||||
NULL, NULL, name,
|
NULL, NULL, name,
|
||||||
@ -396,13 +476,18 @@ profile_destroy(void *arg, dtrace_id_t id, void *parg)
|
|||||||
{
|
{
|
||||||
profile_probe_t *prof = parg;
|
profile_probe_t *prof = parg;
|
||||||
|
|
||||||
|
#ifdef illumos
|
||||||
ASSERT(prof->prof_cyclic == CYCLIC_NONE);
|
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));
|
kmem_free(prof, sizeof (profile_probe_t));
|
||||||
|
|
||||||
ASSERT(profile_total >= 1);
|
ASSERT(profile_total >= 1);
|
||||||
atomic_add_32(&profile_total, -1);
|
atomic_add_32(&profile_total, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef illumos
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
static void
|
static void
|
||||||
profile_online(void *arg, cpu_t *cpu, cyc_handler_t *hdlr, cyc_time_t *when)
|
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;
|
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
|
static void
|
||||||
profile_load(void *dummy)
|
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);
|
DEV_MODULE(profile, profile_modevent, NULL);
|
||||||
MODULE_VERSION(profile, 1);
|
MODULE_VERSION(profile, 1);
|
||||||
MODULE_DEPEND(profile, dtrace, 1, 1, 1);
|
MODULE_DEPEND(profile, dtrace, 1, 1, 1);
|
||||||
MODULE_DEPEND(profile, cyclic, 1, 1, 1);
|
|
||||||
MODULE_DEPEND(profile, opensolaris, 1, 1, 1);
|
MODULE_DEPEND(profile, opensolaris, 1, 1, 1);
|
||||||
|
@ -695,6 +695,7 @@ struct sge {
|
|||||||
struct sge_iq **iqmap; /* iq->cntxt_id to iq mapping */
|
struct sge_iq **iqmap; /* iq->cntxt_id to iq mapping */
|
||||||
struct sge_eq **eqmap; /* eq->cntxt_id to eq mapping */
|
struct sge_eq **eqmap; /* eq->cntxt_id to eq mapping */
|
||||||
|
|
||||||
|
int pad_boundary;
|
||||||
int pack_boundary;
|
int pack_boundary;
|
||||||
int8_t safe_hwidx1; /* may not have room for metadata */
|
int8_t safe_hwidx1; /* may not have room for metadata */
|
||||||
int8_t safe_hwidx2; /* with room for metadata and maybe more */
|
int8_t safe_hwidx2; /* with room for metadata and maybe more */
|
||||||
|
@ -120,19 +120,10 @@ TUNABLE_INT("hw.cxgbe.buffer_packing", &buffer_packing);
|
|||||||
/*
|
/*
|
||||||
* Start next frame in a packed buffer at this boundary.
|
* Start next frame in a packed buffer at this boundary.
|
||||||
* -1: driver should figure out a good value.
|
* -1: driver should figure out a good value.
|
||||||
* T4:
|
* 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.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
static int fl_pack = -1;
|
static int fl_pack = -1;
|
||||||
static int t4_fl_pack;
|
|
||||||
static int t5_fl_pack;
|
|
||||||
TUNABLE_INT("hw.cxgbe.fl_pack", &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 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 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_iq(struct sge_iq *, struct adapter *, int, int, int);
|
||||||
static inline void init_fl(struct adapter *, struct sge_fl *, int, int, int,
|
static inline void init_fl(struct adapter *, struct sge_fl *, int, int, char *);
|
||||||
char *);
|
|
||||||
static inline void init_eq(struct sge_eq *, int, int, uint8_t, uint16_t,
|
static inline void init_eq(struct sge_eq *, int, int, uint8_t, uint16_t,
|
||||||
char *);
|
char *);
|
||||||
static int alloc_ring(struct adapter *, size_t, bus_dma_tag_t *, bus_dmamap_t *,
|
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
|
void
|
||||||
t4_sge_modload(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) {
|
if (fl_pktshift < 0 || fl_pktshift > 7) {
|
||||||
printf("Invalid hw.cxgbe.fl_pktshift value (%d),"
|
printf("Invalid hw.cxgbe.fl_pktshift value (%d),"
|
||||||
@ -280,35 +261,6 @@ t4_sge_modload(void)
|
|||||||
fl_pktshift = 2;
|
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) {
|
if (spg_len != 64 && spg_len != 128) {
|
||||||
int len;
|
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);
|
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.
|
* 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;
|
m = V_PKTSHIFT(M_PKTSHIFT) | F_RXPKTCPLMODE | F_EGRSTATUSPAGESIZE;
|
||||||
v = V_PKTSHIFT(fl_pktshift) | F_RXPKTCPLMODE |
|
v = V_PKTSHIFT(fl_pktshift) | F_RXPKTCPLMODE |
|
||||||
V_EGRSTATUSPAGESIZE(spg_len == 128);
|
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);
|
t4_set_reg_field(sc, A_SGE_CONTROL, m, v);
|
||||||
|
|
||||||
if (is_t5(sc) && buffer_packing) {
|
setup_pad_and_pack_boundaries(sc);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
v = V_HOSTPAGESIZEPF0(PAGE_SHIFT - 10) |
|
v = V_HOSTPAGESIZEPF0(PAGE_SHIFT - 10) |
|
||||||
V_HOSTPAGESIZEPF1(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
|
* SGE wants the buffer to be at least 64B and then a multiple of 16. If
|
||||||
* boundary or 16, whichever is greater.
|
* 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
|
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);
|
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;
|
m = V_PKTSHIFT(M_PKTSHIFT) | F_RXPKTCPLMODE | F_EGRSTATUSPAGESIZE;
|
||||||
v = V_PKTSHIFT(fl_pktshift) | F_RXPKTCPLMODE |
|
v = V_PKTSHIFT(fl_pktshift) | F_RXPKTCPLMODE |
|
||||||
V_EGRSTATUSPAGESIZE(spg_len == 128);
|
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);
|
r = t4_read_reg(sc, A_SGE_CONTROL);
|
||||||
if ((r & m) != v) {
|
if ((r & m) != v) {
|
||||||
device_printf(sc->dev, "invalid SGE_CONTROL(0x%x)\n", r);
|
device_printf(sc->dev, "invalid SGE_CONTROL(0x%x)\n", r);
|
||||||
rc = EINVAL;
|
rc = EINVAL;
|
||||||
}
|
}
|
||||||
|
s->pad_boundary = 1 << (G_INGPADBOUNDARY(r) + 5);
|
||||||
|
|
||||||
if (is_t5(sc) && buffer_packing) {
|
if (is_t4(sc))
|
||||||
m = V_INGPACKBOUNDARY(M_INGPACKBOUNDARY);
|
s->pack_boundary = s->pad_boundary;
|
||||||
if (t5_fl_pack == 16)
|
else {
|
||||||
v = V_INGPACKBOUNDARY(0);
|
|
||||||
else
|
|
||||||
v = V_INGPACKBOUNDARY(ilog2(t5_fl_pack) - 5);
|
|
||||||
r = t4_read_reg(sc, A_SGE_CONTROL2);
|
r = t4_read_reg(sc, A_SGE_CONTROL2);
|
||||||
if ((r & m) != v) {
|
if (G_INGPACKBOUNDARY(r) == 0)
|
||||||
device_printf(sc->dev,
|
s->pack_boundary = 16;
|
||||||
"invalid SGE_CONTROL2(0x%x)\n", r);
|
else
|
||||||
rc = EINVAL;
|
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 = V_HOSTPAGESIZEPF0(PAGE_SHIFT - 10) |
|
||||||
V_HOSTPAGESIZEPF1(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++) {
|
for (i = 0; i < nitems(s->hw_buf_info); i++, hwb++) {
|
||||||
r = t4_read_reg(sc, A_SGE_FL_BUFFER_SIZE0 + (4 * i));
|
r = t4_read_reg(sc, A_SGE_FL_BUFFER_SIZE0 + (4 * i));
|
||||||
hwb->size = r;
|
hwb->size = r;
|
||||||
hwb->zidx = hwsz_ok(r) ? -1 : -2;
|
hwb->zidx = hwsz_ok(sc, r) ? -1 : -2;
|
||||||
hwb->next = -1;
|
hwb->next = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a sorted list in decreasing order of hw buffer sizes (and so
|
* Create a sorted list in decreasing order of hw buffer sizes (and so
|
||||||
* increasing order of spare area) for each software zone.
|
* 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 */
|
n = 0; /* no usable buffer size to begin with */
|
||||||
swz = &s->sw_zone_info[0];
|
swz = &s->sw_zone_info[0];
|
||||||
@ -586,6 +589,12 @@ t4_read_chip_settings(struct adapter *sc)
|
|||||||
swz->zone = m_getzone(swz->size);
|
swz->zone = m_getzone(swz->size);
|
||||||
swz->type = m_gettype(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)
|
if (swz->size == safest_rx_cluster)
|
||||||
safe_swz = swz;
|
safe_swz = swz;
|
||||||
|
|
||||||
@ -593,6 +602,10 @@ t4_read_chip_settings(struct adapter *sc)
|
|||||||
for (j = 0; j < SGE_FLBUF_SIZES; j++, hwb++) {
|
for (j = 0; j < SGE_FLBUF_SIZES; j++, hwb++) {
|
||||||
if (hwb->zidx != -1 || hwb->size > swz->size)
|
if (hwb->zidx != -1 || hwb->size > swz->size)
|
||||||
continue;
|
continue;
|
||||||
|
#ifdef INVARIANTS
|
||||||
|
if (fl_pad)
|
||||||
|
MPASS(hwb->size % sc->sge.pad_boundary == 0);
|
||||||
|
#endif
|
||||||
hwb->zidx = i;
|
hwb->zidx = i;
|
||||||
if (head == -1)
|
if (head == -1)
|
||||||
head = tail = j;
|
head = tail = j;
|
||||||
@ -640,14 +653,15 @@ t4_read_chip_settings(struct adapter *sc)
|
|||||||
int spare;
|
int spare;
|
||||||
|
|
||||||
hwb = &s->hw_buf_info[i];
|
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;
|
spare = safe_swz->size - hwb->size;
|
||||||
if (spare < CL_METADATA_SIZE)
|
if (spare >= CL_METADATA_SIZE) {
|
||||||
continue;
|
|
||||||
if (s->safe_hwidx2 == -1 ||
|
|
||||||
spare == CL_METADATA_SIZE + MSIZE)
|
|
||||||
s->safe_hwidx2 = i;
|
s->safe_hwidx2 = i;
|
||||||
if (spare >= CL_METADATA_SIZE + MSIZE)
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -745,17 +759,6 @@ t4_create_dma_tag(struct adapter *sc)
|
|||||||
return (rc);
|
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
|
void
|
||||||
t4_sge_sysctls(struct adapter *sc, struct sysctl_ctx_list *ctx,
|
t4_sge_sysctls(struct adapter *sc, struct sysctl_ctx_list *ctx,
|
||||||
struct sysctl_oid_list *children)
|
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)");
|
NULL, fl_pktshift, "payload DMA offset in rx buffer (bytes)");
|
||||||
|
|
||||||
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "fl_pad", CTLFLAG_RD,
|
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,
|
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "spg_len", CTLFLAG_RD,
|
||||||
NULL, spg_len, "status page size (bytes)");
|
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,
|
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "cong_drop", CTLFLAG_RD,
|
||||||
NULL, cong_drop, "congestion drop setting");
|
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,
|
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "fl_pack", CTLFLAG_RD,
|
||||||
NULL, sc->sge.pack_boundary, "payload pack boundary (bytes)");
|
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
|
#ifdef TCP_OFFLOAD
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
payload = roundup2(payload, fl_pad);
|
|
||||||
|
|
||||||
return (payload);
|
return (payload);
|
||||||
}
|
}
|
||||||
@ -983,7 +981,7 @@ t4_setup_port_queues(struct port_info *pi)
|
|||||||
struct ifnet *ifp = pi->ifp;
|
struct ifnet *ifp = pi->ifp;
|
||||||
struct sysctl_oid *oid = device_get_sysctl_tree(pi->dev);
|
struct sysctl_oid *oid = device_get_sysctl_tree(pi->dev);
|
||||||
struct sysctl_oid_list *children = SYSCTL_CHILDREN(oid);
|
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) */
|
/* Interrupt vector to start from (when using multiple vectors) */
|
||||||
intr_idx = first_vector(pi);
|
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.
|
* b) allocate queue iff it will take direct interrupts.
|
||||||
*/
|
*/
|
||||||
maxp = mtu_to_max_payload(sc, mtu, 0);
|
maxp = mtu_to_max_payload(sc, mtu, 0);
|
||||||
pack = enable_buffer_packing(sc);
|
|
||||||
if (pi->flags & INTR_RXQ) {
|
if (pi->flags & INTR_RXQ) {
|
||||||
oid = SYSCTL_ADD_NODE(&pi->ctx, children, OID_AUTO, "rxq",
|
oid = SYSCTL_ADD_NODE(&pi->ctx, children, OID_AUTO, "rxq",
|
||||||
CTLFLAG_RD, NULL, "rx queues");
|
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",
|
snprintf(name, sizeof(name), "%s rxq%d-fl",
|
||||||
device_get_nameunit(pi->dev), i);
|
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) {
|
if (pi->flags & INTR_RXQ) {
|
||||||
rxq->iq.flags |= IQ_INTR;
|
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",
|
snprintf(name, sizeof(name), "%s ofld_rxq%d-fl",
|
||||||
device_get_nameunit(pi->dev), i);
|
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) {
|
if (pi->flags & INTR_OFLD_RXQ) {
|
||||||
ofld_rxq->iq.flags |= IQ_INTR;
|
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
|
* d) m_extaddref (cluster with metadata) zone_mbuf
|
||||||
*/
|
*/
|
||||||
static struct 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 mbuf *m;
|
||||||
struct fl_sdesc *sd = &fl->sdesc[fl->cidx];
|
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 sw_zone_info *swz = &sc->sge.sw_zone_info[cll->zidx];
|
||||||
struct hw_buf_info *hwb = &sc->sge.hw_buf_info[cll->hwidx];
|
struct hw_buf_info *hwb = &sc->sge.hw_buf_info[cll->hwidx];
|
||||||
struct cluster_metadata *clm = cl_metadata(sc, fl, cll, sd->cl);
|
struct cluster_metadata *clm = cl_metadata(sc, fl, cll, sd->cl);
|
||||||
int len, padded_len;
|
int len, blen;
|
||||||
caddr_t payload;
|
caddr_t payload;
|
||||||
|
|
||||||
len = min(total, hwb->size - fl->rx_offset);
|
blen = hwb->size - fl->rx_offset; /* max possible in this buf */
|
||||||
padded_len = roundup2(len, fl->buf_boundary);
|
len = min(remaining, blen);
|
||||||
payload = sd->cl + cll->region1 + fl->rx_offset;
|
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) {
|
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.
|
* 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);
|
m_gethdr(M_NOWAIT, MT_DATA) : m_get(M_NOWAIT, MT_DATA);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -1603,10 +1612,11 @@ get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int total, int flags)
|
|||||||
MPASS(clm != NULL);
|
MPASS(clm != NULL);
|
||||||
m = (struct mbuf *)(sd->cl + sd->nmbuf * MSIZE);
|
m = (struct mbuf *)(sd->cl + sd->nmbuf * MSIZE);
|
||||||
/* No bzero required */
|
/* 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);
|
return (NULL);
|
||||||
fl->mbuf_inlined++;
|
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);
|
swz->zone, sd->cl);
|
||||||
if (sd->nmbuf++ == 0)
|
if (sd->nmbuf++ == 0)
|
||||||
counter_u64_add(extfree_refs, 1);
|
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.
|
* payload in the cluster.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
m = flags & M_PKTHDR ?
|
m = fr_offset == 0 ?
|
||||||
m_gethdr(M_NOWAIT, MT_DATA) : m_get(M_NOWAIT, MT_DATA);
|
m_gethdr(M_NOWAIT, MT_DATA) : m_get(M_NOWAIT, MT_DATA);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
fl->mbuf_allocated++;
|
fl->mbuf_allocated++;
|
||||||
if (clm != NULL) {
|
if (clm != NULL) {
|
||||||
m_extaddref(m, payload, padded_len, &clm->refcount,
|
m_extaddref(m, payload, blen, &clm->refcount,
|
||||||
rxb_free, swz->zone, sd->cl);
|
rxb_free, swz->zone, sd->cl);
|
||||||
if (sd->nmbuf++ == 0)
|
if (sd->nmbuf++ == 0)
|
||||||
counter_u64_add(extfree_refs, 1);
|
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 */
|
sd->cl = NULL; /* consumed, not a recycle candidate */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags & M_PKTHDR)
|
if (fr_offset == 0)
|
||||||
m->m_pkthdr.len = total;
|
m->m_pkthdr.len = remaining;
|
||||||
m->m_len = len;
|
m->m_len = len;
|
||||||
|
|
||||||
if (fl->flags & FL_BUF_PACKING) {
|
if (fl->flags & FL_BUF_PACKING) {
|
||||||
fl->rx_offset += padded_len;
|
fl->rx_offset += blen;
|
||||||
MPASS(fl->rx_offset <= hwb->size);
|
MPASS(fl->rx_offset <= hwb->size);
|
||||||
if (fl->rx_offset < hwb->size)
|
if (fl->rx_offset < hwb->size)
|
||||||
return (m); /* without advancing the cidx */
|
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)
|
get_fl_payload(struct adapter *sc, struct sge_fl *fl, uint32_t len_newbuf)
|
||||||
{
|
{
|
||||||
struct mbuf *m0, *m, **pnext;
|
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)) {
|
if (__predict_false(fl->flags & FL_BUF_RESUME)) {
|
||||||
M_ASSERTPKTHDR(fl->m0);
|
M_ASSERTPKTHDR(fl->m0);
|
||||||
MPASS(len == fl->m0->m_pkthdr.len);
|
MPASS(fl->m0->m_pkthdr.len == total);
|
||||||
MPASS(fl->remaining < len);
|
MPASS(fl->remaining < total);
|
||||||
|
|
||||||
m0 = fl->m0;
|
m0 = fl->m0;
|
||||||
pnext = fl->pnext;
|
pnext = fl->pnext;
|
||||||
len = fl->remaining;
|
remaining = fl->remaining;
|
||||||
fl->flags &= ~FL_BUF_RESUME;
|
fl->flags &= ~FL_BUF_RESUME;
|
||||||
goto get_segment;
|
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.
|
* '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)
|
if (m0 == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
len -= m0->m_len;
|
remaining = total - m0->m_len;
|
||||||
pnext = &m0->m_next;
|
pnext = &m0->m_next;
|
||||||
while (len > 0) {
|
while (remaining > 0) {
|
||||||
get_segment:
|
get_segment:
|
||||||
MPASS(fl->rx_offset == 0);
|
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)) {
|
if (__predict_false(m == NULL)) {
|
||||||
fl->m0 = m0;
|
fl->m0 = m0;
|
||||||
fl->pnext = pnext;
|
fl->pnext = pnext;
|
||||||
fl->remaining = len;
|
fl->remaining = remaining;
|
||||||
fl->flags |= FL_BUF_RESUME;
|
fl->flags |= FL_BUF_RESUME;
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
*pnext = m;
|
*pnext = m;
|
||||||
pnext = &m->m_next;
|
pnext = &m->m_next;
|
||||||
len -= m->m_len;
|
remaining -= m->m_len;
|
||||||
}
|
}
|
||||||
*pnext = NULL;
|
*pnext = NULL;
|
||||||
|
|
||||||
@ -2121,14 +2131,15 @@ init_iq(struct sge_iq *iq, struct adapter *sc, int tmr_idx, int pktc_idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
init_fl(struct adapter *sc, struct sge_fl *fl, int qsize, int maxp, int pack,
|
init_fl(struct adapter *sc, struct sge_fl *fl, int qsize, int maxp, char *name)
|
||||||
char *name)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
fl->qsize = qsize;
|
fl->qsize = qsize;
|
||||||
fl->sidx = qsize - spg_len / EQ_ESIZE;
|
fl->sidx = qsize - spg_len / EQ_ESIZE;
|
||||||
strlcpy(fl->lockname, name, sizeof(fl->lockname));
|
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;
|
fl->flags |= FL_BUF_PACKING;
|
||||||
find_best_refill_source(sc, fl, maxp);
|
find_best_refill_source(sc, fl, maxp);
|
||||||
find_safe_refill_source(sc, fl);
|
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) {
|
if (fl->flags & FL_BUF_PACKING) {
|
||||||
fl->lowat = roundup2(sc->sge.fl_starve_threshold2, 8);
|
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 {
|
} else {
|
||||||
fl->lowat = roundup2(sc->sge.fl_starve_threshold, 8);
|
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 |=
|
c.iqns_to_fl0congen |=
|
||||||
htobe32(V_FW_IQ_CMD_FL0HOSTFCMODE(X_HOSTFCMODE_NONE) |
|
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",
|
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cntxt_id",
|
||||||
CTLTYPE_INT | CTLFLAG_RD, &fl->cntxt_id, 0, sysctl_uint16, "I",
|
CTLTYPE_INT | CTLFLAG_RD, &fl->cntxt_id, 0, sysctl_uint16, "I",
|
||||||
"SGE context id of the freelist");
|
"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,
|
SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "cidx", CTLFLAG_RD, &fl->cidx,
|
||||||
0, "consumer index");
|
0, "consumer index");
|
||||||
if (fl->flags & FL_BUF_PACKING) {
|
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)
|
if (allow_mbufs_in_cluster == 0 || hwb->size < maxp)
|
||||||
break;
|
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)
|
if (spare < CL_METADATA_SIZE + MSIZE)
|
||||||
continue;
|
continue;
|
||||||
n = (spare - CL_METADATA_SIZE) / MSIZE;
|
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;
|
spare = swz->size - hwb->size;
|
||||||
fl->cll_alt.hwidx = hwidx;
|
fl->cll_alt.hwidx = hwidx;
|
||||||
fl->cll_alt.zidx = hwb->zidx;
|
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;
|
fl->cll_alt.region1 = ((spare - CL_METADATA_SIZE) / MSIZE) * MSIZE;
|
||||||
else
|
else
|
||||||
fl->cll_alt.region1 = 0;
|
fl->cll_alt.region1 = 0;
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
#include <sys/callout.h>
|
#include <sys/callout.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/priv.h>
|
#include <sys/priv.h>
|
||||||
|
#include <sys/libkern.h>
|
||||||
|
|
||||||
#include <dev/usb/usb.h>
|
#include <dev/usb/usb.h>
|
||||||
#include <dev/usb/usbdi.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)
|
saf1761_host_channel_alloc(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
|
||||||
{
|
{
|
||||||
uint32_t map;
|
uint32_t map;
|
||||||
uint32_t x;
|
int x;
|
||||||
|
|
||||||
if (td->channel < SOTG_HOST_CHANNEL_MAX)
|
if (td->channel < SOTG_HOST_CHANNEL_MAX)
|
||||||
return (0);
|
return (0);
|
||||||
@ -227,41 +228,38 @@ saf1761_host_channel_alloc(struct saf1761_otg_softc *sc, struct saf1761_otg_td *
|
|||||||
|
|
||||||
switch (td->ep_type) {
|
switch (td->ep_type) {
|
||||||
case UE_INTERRUPT:
|
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[0] |
|
||||||
sc->sc_host_intr_busy_map[1];
|
sc->sc_host_intr_busy_map[1]);
|
||||||
for (x = ((map & 0xFFFF) == 0xFFFF) ? 16 : 0; x != 32; x++) {
|
/* find first set bit */
|
||||||
if (map & (1 << x))
|
x = ffs(map) - 1;
|
||||||
continue;
|
if (x < 0 || x > 31)
|
||||||
sc->sc_host_intr_map |= (1 << x);
|
break;
|
||||||
td->channel = 32 + x;
|
sc->sc_host_intr_map |= (1U << x);
|
||||||
return (0);
|
td->channel = 32 + x;
|
||||||
}
|
return (0);
|
||||||
break;
|
|
||||||
case UE_ISOCHRONOUS:
|
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[0] |
|
||||||
sc->sc_host_isoc_busy_map[1];
|
sc->sc_host_isoc_busy_map[1]);
|
||||||
for (x = ((map & 0xFFFF) == 0xFFFF) ? 16 : 0; x != 32; x++) {
|
/* find first set bit */
|
||||||
if (map & (1 << x))
|
x = ffs(map) - 1;
|
||||||
continue;
|
if (x < 0 || x > 31)
|
||||||
sc->sc_host_isoc_map |= (1 << x);
|
break;
|
||||||
td->channel = x;
|
sc->sc_host_isoc_map |= (1U << x);
|
||||||
return (0);
|
td->channel = x;
|
||||||
}
|
return (0);
|
||||||
break;
|
|
||||||
default:
|
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[0] |
|
||||||
sc->sc_host_async_busy_map[1];
|
sc->sc_host_async_busy_map[1]);
|
||||||
for (x = ((map & 0xFFFF) == 0xFFFF) ? 16 : 0; x != 32; x++) {
|
/* find first set bit */
|
||||||
if (map & (1 << x))
|
x = ffs(map) - 1;
|
||||||
continue;
|
if (x < 0 || x > 31)
|
||||||
sc->sc_host_async_map |= (1 << x);
|
break;
|
||||||
td->channel = 64 + x;
|
sc->sc_host_async_map |= (1U << x);
|
||||||
return (0);
|
td->channel = 64 + x;
|
||||||
}
|
return (0);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -278,27 +276,27 @@ saf1761_host_channel_free(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
|
|||||||
case UE_INTERRUPT:
|
case UE_INTERRUPT:
|
||||||
x = td->channel - 32;
|
x = td->channel - 32;
|
||||||
td->channel = SOTG_HOST_CHANNEL_MAX;
|
td->channel = SOTG_HOST_CHANNEL_MAX;
|
||||||
sc->sc_host_intr_map &= ~(1 << x);
|
sc->sc_host_intr_map &= ~(1U << x);
|
||||||
sc->sc_host_intr_suspend_map &= ~(1 << x);
|
sc->sc_host_intr_suspend_map &= ~(1U << x);
|
||||||
sc->sc_host_intr_busy_map[0] |= (1 << x);
|
sc->sc_host_intr_busy_map[0] |= (1U << x);
|
||||||
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
|
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
|
||||||
(~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
|
(~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
|
||||||
break;
|
break;
|
||||||
case UE_ISOCHRONOUS:
|
case UE_ISOCHRONOUS:
|
||||||
x = td->channel;
|
x = td->channel;
|
||||||
td->channel = SOTG_HOST_CHANNEL_MAX;
|
td->channel = SOTG_HOST_CHANNEL_MAX;
|
||||||
sc->sc_host_isoc_map &= ~(1 << x);
|
sc->sc_host_isoc_map &= ~(1U << x);
|
||||||
sc->sc_host_isoc_suspend_map &= ~(1 << x);
|
sc->sc_host_isoc_suspend_map &= ~(1U << x);
|
||||||
sc->sc_host_isoc_busy_map[0] |= (1 << x);
|
sc->sc_host_isoc_busy_map[0] |= (1U << x);
|
||||||
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
|
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
|
||||||
(~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
|
(~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
x = td->channel - 64;
|
x = td->channel - 64;
|
||||||
td->channel = SOTG_HOST_CHANNEL_MAX;
|
td->channel = SOTG_HOST_CHANNEL_MAX;
|
||||||
sc->sc_host_async_map &= ~(1 << x);
|
sc->sc_host_async_map &= ~(1U << x);
|
||||||
sc->sc_host_async_suspend_map &= ~(1 << x);
|
sc->sc_host_async_suspend_map &= ~(1U << x);
|
||||||
sc->sc_host_async_busy_map[0] |= (1 << x);
|
sc->sc_host_async_busy_map[0] |= (1U << x);
|
||||||
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
|
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
|
||||||
(~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
|
(~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
|
||||||
break;
|
break;
|
||||||
@ -3619,19 +3617,19 @@ saf1761_otg_device_resume(struct usb_device *udev)
|
|||||||
switch (td->ep_type) {
|
switch (td->ep_type) {
|
||||||
case UE_INTERRUPT:
|
case UE_INTERRUPT:
|
||||||
x = td->channel - 32;
|
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,
|
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
|
||||||
(~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
|
(~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
|
||||||
break;
|
break;
|
||||||
case UE_ISOCHRONOUS:
|
case UE_ISOCHRONOUS:
|
||||||
x = td->channel;
|
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,
|
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
|
||||||
(~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
|
(~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
x = td->channel - 64;
|
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,
|
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
|
||||||
(~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
|
(~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
|
||||||
break;
|
break;
|
||||||
@ -3675,19 +3673,19 @@ saf1761_otg_device_suspend(struct usb_device *udev)
|
|||||||
switch (td->ep_type) {
|
switch (td->ep_type) {
|
||||||
case UE_INTERRUPT:
|
case UE_INTERRUPT:
|
||||||
x = td->channel - 32;
|
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,
|
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
|
||||||
(~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
|
(~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
|
||||||
break;
|
break;
|
||||||
case UE_ISOCHRONOUS:
|
case UE_ISOCHRONOUS:
|
||||||
x = td->channel;
|
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,
|
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
|
||||||
(~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
|
(~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
x = td->channel - 64;
|
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,
|
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
|
||||||
(~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
|
(~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
|
||||||
break;
|
break;
|
||||||
|
@ -256,23 +256,24 @@ nvidia_meta_read(struct g_consumer *cp)
|
|||||||
pp->name, error);
|
pp->name, error);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
meta = malloc(sizeof(*meta), M_MD_NVIDIA, M_WAITOK);
|
meta = (struct nvidia_raid_conf *)buf;
|
||||||
memcpy(meta, buf, min(sizeof(*meta), pp->sectorsize));
|
|
||||||
g_free(buf);
|
|
||||||
|
|
||||||
/* Check if this is an NVIDIA RAID struct */
|
/* Check if this is an NVIDIA RAID struct */
|
||||||
if (strncmp(meta->nvidia_id, NVIDIA_MAGIC, strlen(NVIDIA_MAGIC))) {
|
if (strncmp(meta->nvidia_id, NVIDIA_MAGIC, strlen(NVIDIA_MAGIC))) {
|
||||||
G_RAID_DEBUG(1, "NVIDIA signature check failed on %s", pp->name);
|
G_RAID_DEBUG(1, "NVIDIA signature check failed on %s", pp->name);
|
||||||
free(meta, M_MD_NVIDIA);
|
g_free(buf);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
if (meta->config_size > 128 ||
|
if (meta->config_size > 128 ||
|
||||||
meta->config_size < 30) {
|
meta->config_size < 30) {
|
||||||
G_RAID_DEBUG(1, "NVIDIA metadata size looks wrong: %d",
|
G_RAID_DEBUG(1, "NVIDIA metadata size looks wrong: %d",
|
||||||
meta->config_size);
|
meta->config_size);
|
||||||
free(meta, M_MD_NVIDIA);
|
g_free(buf);
|
||||||
return (NULL);
|
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. */
|
/* Check metadata checksum. */
|
||||||
for (checksum = 0, ptr = (uint32_t *)meta,
|
for (checksum = 0, ptr = (uint32_t *)meta,
|
||||||
|
@ -277,15 +277,13 @@ sii_meta_read(struct g_consumer *cp)
|
|||||||
pp->name, error);
|
pp->name, error);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
meta = malloc(sizeof(*meta), M_MD_SII, M_WAITOK);
|
meta = (struct sii_raid_conf *)buf;
|
||||||
memcpy(meta, buf, min(sizeof(*meta), pp->sectorsize));
|
|
||||||
g_free(buf);
|
|
||||||
|
|
||||||
/* Check vendor ID. */
|
/* Check vendor ID. */
|
||||||
if (meta->vendor_id != 0x1095) {
|
if (meta->vendor_id != 0x1095) {
|
||||||
G_RAID_DEBUG(1, "SiI vendor ID check failed on %s (0x%04x)",
|
G_RAID_DEBUG(1, "SiI vendor ID check failed on %s (0x%04x)",
|
||||||
pp->name, meta->vendor_id);
|
pp->name, meta->vendor_id);
|
||||||
free(meta, M_MD_SII);
|
g_free(buf);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,9 +291,12 @@ sii_meta_read(struct g_consumer *cp)
|
|||||||
if (meta->version_major != 2) {
|
if (meta->version_major != 2) {
|
||||||
G_RAID_DEBUG(1, "SiI version check failed on %s (%d.%d)",
|
G_RAID_DEBUG(1, "SiI version check failed on %s (%d.%d)",
|
||||||
pp->name, meta->version_major, meta->version_minor);
|
pp->name, meta->version_major, meta->version_minor);
|
||||||
free(meta, M_MD_SII);
|
g_free(buf);
|
||||||
return (NULL);
|
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. */
|
/* Check metadata checksum. */
|
||||||
for (checksum = 0, ptr = (uint16_t *)meta, i = 0; i <= 159; i++)
|
for (checksum = 0, ptr = (uint16_t *)meta, i = 0; i <= 159; i++)
|
||||||
|
@ -54,11 +54,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <machine/cpu.h>
|
#include <machine/cpu.h>
|
||||||
#include <machine/smp.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_can_deep_sleep = 0; /* C3 state is available. */
|
||||||
int cpu_disable_deep_sleep = 0; /* Timer dies in C3. */
|
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 nextprof; /* Next profclock() event. */
|
||||||
sbintime_t nextcall; /* Next callout event. */
|
sbintime_t nextcall; /* Next callout event. */
|
||||||
sbintime_t nextcallopt; /* Next optional 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 ipi; /* This CPU needs IPI. */
|
||||||
int idle; /* This CPU is in idle mode. */
|
int idle; /* This CPU is in idle mode. */
|
||||||
};
|
};
|
||||||
@ -219,13 +211,6 @@ handleevents(sbintime_t now, int fake)
|
|||||||
callout_process(now);
|
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);
|
t = getnextcpuevent(0);
|
||||||
ET_HW_LOCK(state);
|
ET_HW_LOCK(state);
|
||||||
if (!busy) {
|
if (!busy) {
|
||||||
@ -271,10 +256,6 @@ getnextcpuevent(int idle)
|
|||||||
if (profiling && event > state->nextprof)
|
if (profiling && event > state->nextprof)
|
||||||
event = state->nextprof;
|
event = state->nextprof;
|
||||||
}
|
}
|
||||||
#ifdef KDTRACE_HOOKS
|
|
||||||
if (event > state->nextcyc)
|
|
||||||
event = state->nextcyc;
|
|
||||||
#endif
|
|
||||||
return (event);
|
return (event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,9 +576,6 @@ cpu_initclocks_bsp(void)
|
|||||||
CPU_FOREACH(cpu) {
|
CPU_FOREACH(cpu) {
|
||||||
state = DPCPU_ID_PTR(cpu, timerstate);
|
state = DPCPU_ID_PTR(cpu, timerstate);
|
||||||
mtx_init(&state->et_hw_mtx, "et_hw_mtx", NULL, MTX_SPIN);
|
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->nextcall = SBT_MAX;
|
||||||
state->nextcallopt = SBT_MAX;
|
state->nextcallopt = SBT_MAX;
|
||||||
}
|
}
|
||||||
@ -816,41 +794,6 @@ cpu_et_frequency(struct eventtimer *et, uint64_t newfreq)
|
|||||||
ET_UNLOCK();
|
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
|
void
|
||||||
cpu_new_callout(int cpu, sbintime_t bt, sbintime_t bt_opt)
|
cpu_new_callout(int cpu, sbintime_t bt, sbintime_t bt_opt)
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <machine/asm.h>
|
#include <machine/asm.h>
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ffs - find first set bit, this algorithm isolates the first set
|
* 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 */
|
rsbne r0, r0, r0, lsl #16 /* r0 = X * 0x0450fbaf */
|
||||||
|
|
||||||
/* now lookup in table indexed on top 6 bits of r0 */
|
/* now lookup in table indexed on top 6 bits of r0 */
|
||||||
ldrneb r0, [ r2, r0, lsr #26 ]
|
ldrbne r0, [ r2, r0, lsr #26 ]
|
||||||
|
|
||||||
RET
|
RET
|
||||||
.text;
|
.text;
|
||||||
|
@ -90,7 +90,6 @@ SUBDIR= \
|
|||||||
cuse \
|
cuse \
|
||||||
${_cxgb} \
|
${_cxgb} \
|
||||||
${_cxgbe} \
|
${_cxgbe} \
|
||||||
${_cyclic} \
|
|
||||||
dc \
|
dc \
|
||||||
dcons \
|
dcons \
|
||||||
dcons_crom \
|
dcons_crom \
|
||||||
@ -494,9 +493,6 @@ _cardbus= cardbus
|
|||||||
_cbb= cbb
|
_cbb= cbb
|
||||||
_cpuctl= cpuctl
|
_cpuctl= cpuctl
|
||||||
_cpufreq= cpufreq
|
_cpufreq= cpufreq
|
||||||
.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
|
|
||||||
_cyclic= cyclic
|
|
||||||
.endif
|
|
||||||
_dpms= dpms
|
_dpms= dpms
|
||||||
_drm= drm
|
_drm= drm
|
||||||
_drm2= drm2
|
_drm2= drm2
|
||||||
@ -702,9 +698,6 @@ _cardbus= cardbus
|
|||||||
_cbb= cbb
|
_cbb= cbb
|
||||||
_cfi= cfi
|
_cfi= cfi
|
||||||
_cpufreq= cpufreq
|
_cpufreq= cpufreq
|
||||||
.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
|
|
||||||
_cyclic= cyclic
|
|
||||||
.endif
|
|
||||||
_drm= drm
|
_drm= drm
|
||||||
.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
|
.if ${MK_CDDL} != "no" || defined(ALL_MODULES)
|
||||||
_dtrace= dtrace
|
_dtrace= dtrace
|
||||||
|
@ -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
|
|
@ -3,7 +3,6 @@
|
|||||||
IGNORE_PRAGMA= 1
|
IGNORE_PRAGMA= 1
|
||||||
|
|
||||||
load :
|
load :
|
||||||
-kldload cyclic
|
|
||||||
-kldload dtrace
|
-kldload dtrace
|
||||||
.if ${MACHINE_CPUARCH} == "i386"
|
.if ${MACHINE_CPUARCH} == "i386"
|
||||||
-kldload sdt
|
-kldload sdt
|
||||||
@ -25,5 +24,4 @@ unload :
|
|||||||
-kldunload sdt
|
-kldunload sdt
|
||||||
.endif
|
.endif
|
||||||
-kldunload dtrace
|
-kldunload dtrace
|
||||||
-kldunload cyclic
|
|
||||||
kldstat
|
kldstat
|
||||||
|
@ -63,7 +63,6 @@ DEV_MODULE(dtraceall, dtraceall_modevent, NULL);
|
|||||||
MODULE_VERSION(dtraceall, 1);
|
MODULE_VERSION(dtraceall, 1);
|
||||||
|
|
||||||
/* All the DTrace modules should be dependencies here: */
|
/* 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, opensolaris, 1, 1, 1);
|
||||||
MODULE_DEPEND(dtraceall, dtrace, 1, 1, 1);
|
MODULE_DEPEND(dtraceall, dtrace, 1, 1, 1);
|
||||||
MODULE_DEPEND(dtraceall, dtmalloc, 1, 1, 1);
|
MODULE_DEPEND(dtraceall, dtmalloc, 1, 1, 1);
|
||||||
|
@ -5477,10 +5477,12 @@ __attribute__((noinline))
|
|||||||
if ((ch->chunk_type & 0x40) && (stcb != NULL)) {
|
if ((ch->chunk_type & 0x40) && (stcb != NULL)) {
|
||||||
struct mbuf *mm;
|
struct mbuf *mm;
|
||||||
struct sctp_paramhdr *phd;
|
struct sctp_paramhdr *phd;
|
||||||
|
int len;
|
||||||
|
|
||||||
mm = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
|
mm = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
|
||||||
0, M_NOWAIT, 1, MT_DATA);
|
0, M_NOWAIT, 1, MT_DATA);
|
||||||
if (mm) {
|
if (mm) {
|
||||||
|
len = min(SCTP_SIZE32(chk_length), (uint32_t) (length - *offset));
|
||||||
phd = mtod(mm, struct sctp_paramhdr *);
|
phd = mtod(mm, struct sctp_paramhdr *);
|
||||||
/*
|
/*
|
||||||
* We cheat and use param type since
|
* We cheat and use param type since
|
||||||
@ -5490,11 +5492,11 @@ __attribute__((noinline))
|
|||||||
* names.
|
* names.
|
||||||
*/
|
*/
|
||||||
phd->param_type = htons(SCTP_CAUSE_UNRECOG_CHUNK);
|
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_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_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);
|
sctp_m_freem(mm);
|
||||||
} else {
|
} else {
|
||||||
#ifdef SCTP_MBUF_LOGGING
|
#ifdef SCTP_MBUF_LOGGING
|
||||||
|
@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <netinet/sctp_header.h>
|
#include <netinet/sctp_header.h>
|
||||||
#include <netinet/sctp_var.h>
|
#include <netinet/sctp_var.h>
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
|
#include <netinet6/sctp6_var.h>
|
||||||
#endif
|
#endif
|
||||||
#include <netinet/sctp_sysctl.h>
|
#include <netinet/sctp_sysctl.h>
|
||||||
#include <netinet/sctp_output.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) {
|
switch (sctp_ifa->address.sa.sa_family) {
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
#ifdef INET6
|
||||||
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
|
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
|
||||||
cnt += sizeof(struct sockaddr_in6);
|
cnt += sizeof(struct sockaddr_in6);
|
||||||
else
|
else
|
||||||
cnt += sizeof(struct sockaddr_in);
|
cnt += sizeof(struct sockaddr_in);
|
||||||
|
#else
|
||||||
|
cnt += sizeof(struct sockaddr_in);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#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) {
|
switch (laddr->ifa->address.sa.sa_family) {
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
#ifdef INET6
|
||||||
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
|
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
|
||||||
cnt += sizeof(struct sockaddr_in6);
|
cnt += sizeof(struct sockaddr_in6);
|
||||||
else
|
else
|
||||||
cnt += sizeof(struct sockaddr_in);
|
cnt += sizeof(struct sockaddr_in);
|
||||||
|
#else
|
||||||
|
cnt += sizeof(struct sockaddr_in);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
@ -2216,23 +2225,27 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
size = 0;
|
size = 0;
|
||||||
/* Count the sizes */
|
/* Count the sizes */
|
||||||
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
||||||
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
|
switch (net->ro._l_addr.sa.sa_family) {
|
||||||
size += sizeof(struct sockaddr_in6);
|
|
||||||
} else {
|
|
||||||
switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
|
|
||||||
#ifdef INET
|
#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);
|
size += sizeof(struct sockaddr_in);
|
||||||
break;
|
}
|
||||||
|
#else
|
||||||
|
size += sizeof(struct sockaddr_in);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
size += sizeof(struct sockaddr_in6);
|
size += sizeof(struct sockaddr_in6);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
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];
|
sas = (struct sockaddr_storage *)&saddr->addr[0];
|
||||||
|
|
||||||
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
||||||
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
|
switch (net->ro._l_addr.sa.sa_family) {
|
||||||
cpsz = sizeof(struct sockaddr_in6);
|
|
||||||
} else {
|
|
||||||
switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
|
|
||||||
#ifdef INET
|
#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);
|
cpsz = sizeof(struct sockaddr_in);
|
||||||
break;
|
}
|
||||||
|
#else
|
||||||
|
cpsz = sizeof(struct sockaddr_in);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
cpsz = sizeof(struct sockaddr_in6);
|
cpsz = sizeof(struct sockaddr_in6);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
cpsz = 0;
|
cpsz = 0;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (cpsz == 0) {
|
if (cpsz == 0) {
|
||||||
break;
|
break;
|
||||||
@ -2292,15 +2309,15 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
}
|
}
|
||||||
#if defined(INET) && defined(INET6)
|
#if defined(INET) && defined(INET6)
|
||||||
if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) &&
|
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 */
|
/* 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);
|
(struct sockaddr_in6 *)sas);
|
||||||
} else {
|
} else {
|
||||||
#endif
|
|
||||||
memcpy(sas, &net->ro._l_addr, cpsz);
|
memcpy(sas, &net->ro._l_addr, cpsz);
|
||||||
#if defined(INET) && defined(INET6)
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
memcpy(sas, &net->ro._l_addr, cpsz);
|
||||||
#endif
|
#endif
|
||||||
((struct sockaddr_in *)sas)->sin_port = stcb->rport;
|
((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_paddrparams *paddrp;
|
||||||
struct sctp_nets *net;
|
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_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, *optsize);
|
||||||
SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
|
SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
|
||||||
|
|
||||||
net = NULL;
|
#if defined(INET) && defined(INET6)
|
||||||
if (stcb) {
|
if (paddrp->spp_address.ss_family == AF_INET6) {
|
||||||
net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
|
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 {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We increment here since
|
* 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
|
* the locked tcb (last argument) is NOT a
|
||||||
* TCB.. aka NULL.
|
* TCB.. aka NULL.
|
||||||
*/
|
*/
|
||||||
|
net = NULL;
|
||||||
SCTP_INP_INCR_REF(inp);
|
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) {
|
if (stcb == NULL) {
|
||||||
SCTP_INP_DECR_REF(inp);
|
SCTP_INP_DECR_REF(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb && (net == NULL)) {
|
if ((stcb != NULL) && (net == NULL)) {
|
||||||
struct sockaddr *sa;
|
|
||||||
|
|
||||||
sa = (struct sockaddr *)&paddrp->spp_address;
|
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
if (sa->sa_family == AF_INET) {
|
if (addr->sa_family == AF_INET) {
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
sin = (struct sockaddr_in *)sa;
|
sin = (struct sockaddr_in *)addr;
|
||||||
if (sin->sin_addr.s_addr) {
|
if (sin->sin_addr.s_addr != INADDR_ANY) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
|
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
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
if (sa->sa_family == AF_INET6) {
|
if (addr->sa_family == AF_INET6) {
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *)sa;
|
sin6 = (struct sockaddr_in6 *)addr;
|
||||||
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
@ -2395,10 +2432,10 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb) {
|
if (stcb != NULL) {
|
||||||
/* Applies to the specific association */
|
/* Applies to the specific association */
|
||||||
paddrp->spp_flags = 0;
|
paddrp->spp_flags = 0;
|
||||||
if (net) {
|
if (net != NULL) {
|
||||||
int ovh;
|
int ovh;
|
||||||
|
|
||||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
|
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_paddrinfo *paddri;
|
||||||
struct sctp_nets *net;
|
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_CHECK_AND_CAST(paddri, optval, struct sctp_paddrinfo, *optsize);
|
||||||
SCTP_FIND_STCB(inp, stcb, paddri->spinfo_assoc_id);
|
SCTP_FIND_STCB(inp, stcb, paddri->spinfo_assoc_id);
|
||||||
|
|
||||||
net = NULL;
|
#if defined(INET) && defined(INET6)
|
||||||
if (stcb) {
|
if (paddri->spinfo_address.ss_family == AF_INET6) {
|
||||||
net = sctp_findnet(stcb, (struct sockaddr *)&paddri->spinfo_address);
|
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 {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We increment here since
|
* 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
|
* the locked tcb (last argument) is NOT a
|
||||||
* TCB.. aka NULL.
|
* TCB.. aka NULL.
|
||||||
*/
|
*/
|
||||||
|
net = NULL;
|
||||||
SCTP_INP_INCR_REF(inp);
|
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) {
|
if (stcb == NULL) {
|
||||||
SCTP_INP_DECR_REF(inp);
|
SCTP_INP_DECR_REF(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((stcb) && (net)) {
|
if ((stcb != NULL) && (net != NULL)) {
|
||||||
if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
|
if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
|
||||||
/* It's unconfirmed */
|
/* It's unconfirmed */
|
||||||
paddri->spinfo_state = SCTP_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);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
*optsize = sizeof(struct sctp_paddrinfo);
|
*optsize = sizeof(struct sctp_paddrinfo);
|
||||||
} else {
|
} else {
|
||||||
if (stcb) {
|
if (stcb != NULL) {
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
}
|
}
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
|
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);
|
SCTP_FIND_STCB(inp, stcb, ssp->ssp_assoc_id);
|
||||||
|
|
||||||
if (stcb) {
|
if (stcb) {
|
||||||
/* simply copy out the sockaddr_storage... */
|
union sctp_sockstore *addr;
|
||||||
size_t len;
|
|
||||||
|
|
||||||
len = *optsize;
|
addr = &stcb->asoc.primary_destination->ro._l_addr;
|
||||||
if (len > stcb->asoc.primary_destination->ro._l_addr.sa.sa_len)
|
switch (addr->sa.sa_family) {
|
||||||
len = stcb->asoc.primary_destination->ro._l_addr.sa.sa_len;
|
#ifdef INET
|
||||||
|
case AF_INET:
|
||||||
memcpy(&ssp->ssp_addr,
|
#ifdef INET6
|
||||||
&stcb->asoc.primary_destination->ro._l_addr,
|
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
|
||||||
len);
|
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);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
*optsize = sizeof(struct sctp_setprim);
|
*optsize = sizeof(struct sctp_setprim);
|
||||||
} else {
|
} else {
|
||||||
@ -3121,13 +3197,35 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
{
|
{
|
||||||
struct sctp_paddrthlds *thlds;
|
struct sctp_paddrthlds *thlds;
|
||||||
struct sctp_nets *net;
|
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_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, *optsize);
|
||||||
SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
|
SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
|
||||||
|
|
||||||
net = NULL;
|
#if defined(INET) && defined(INET6)
|
||||||
if (stcb) {
|
if (thlds->spt_address.ss_family == AF_INET6) {
|
||||||
net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address);
|
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 {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We increment here since
|
* 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
|
* the locked tcb (last argument) is NOT a
|
||||||
* TCB.. aka NULL.
|
* TCB.. aka NULL.
|
||||||
*/
|
*/
|
||||||
|
net = NULL;
|
||||||
SCTP_INP_INCR_REF(inp);
|
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) {
|
if (stcb == NULL) {
|
||||||
SCTP_INP_DECR_REF(inp);
|
SCTP_INP_DECR_REF(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb && (net == NULL)) {
|
if ((stcb != NULL) && (net == NULL)) {
|
||||||
struct sockaddr *sa;
|
|
||||||
|
|
||||||
sa = (struct sockaddr *)&thlds->spt_address;
|
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
if (sa->sa_family == AF_INET) {
|
if (addr->sa_family == AF_INET) {
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
sin = (struct sockaddr_in *)sa;
|
sin = (struct sockaddr_in *)addr;
|
||||||
if (sin->sin_addr.s_addr) {
|
if (sin->sin_addr.s_addr != INADDR_ANY) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
|
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
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
if (sa->sa_family == AF_INET6) {
|
if (addr->sa_family == AF_INET6) {
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *)sa;
|
sin6 = (struct sockaddr_in6 *)addr;
|
||||||
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
@ -3179,8 +3275,8 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb) {
|
if (stcb != NULL) {
|
||||||
if (net) {
|
if (net != NULL) {
|
||||||
thlds->spt_pathmaxrxt = net->failure_threshold;
|
thlds->spt_pathmaxrxt = net->failure_threshold;
|
||||||
thlds->spt_pathpfthld = net->pf_threshold;
|
thlds->spt_pathpfthld = net->pf_threshold;
|
||||||
} else {
|
} else {
|
||||||
@ -3212,12 +3308,35 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
{
|
{
|
||||||
struct sctp_udpencaps *encaps;
|
struct sctp_udpencaps *encaps;
|
||||||
struct sctp_nets *net;
|
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_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, *optsize);
|
||||||
SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id);
|
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) {
|
if (stcb) {
|
||||||
net = sctp_findnet(stcb, (struct sockaddr *)&encaps->sue_address);
|
net = sctp_findnet(stcb, addr);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We increment here since
|
* We increment here since
|
||||||
@ -3228,21 +3347,18 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
*/
|
*/
|
||||||
net = NULL;
|
net = NULL;
|
||||||
SCTP_INP_INCR_REF(inp);
|
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) {
|
if (stcb == NULL) {
|
||||||
SCTP_INP_DECR_REF(inp);
|
SCTP_INP_DECR_REF(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb && (net == NULL)) {
|
if ((stcb != NULL) && (net == NULL)) {
|
||||||
struct sockaddr *sa;
|
|
||||||
|
|
||||||
sa = (struct sockaddr *)&encaps->sue_address;
|
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
if (sa->sa_family == AF_INET) {
|
if (addr->sa_family == AF_INET) {
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
sin = (struct sockaddr_in *)sa;
|
sin = (struct sockaddr_in *)addr;
|
||||||
if (sin->sin_addr.s_addr) {
|
if (sin->sin_addr.s_addr != INADDR_ANY) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
|
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
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
if (sa->sa_family == AF_INET6) {
|
if (addr->sa_family == AF_INET6) {
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *)sa;
|
sin6 = (struct sockaddr_in6 *)addr;
|
||||||
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
@ -3270,7 +3386,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb) {
|
if (stcb != NULL) {
|
||||||
if (net) {
|
if (net) {
|
||||||
encaps->sue_port = net->port;
|
encaps->sue_port = net->port;
|
||||||
} else {
|
} else {
|
||||||
@ -4946,12 +5062,35 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
{
|
{
|
||||||
struct sctp_paddrparams *paddrp;
|
struct sctp_paddrparams *paddrp;
|
||||||
struct sctp_nets *net;
|
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_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, optsize);
|
||||||
SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
|
SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
|
||||||
net = NULL;
|
|
||||||
if (stcb) {
|
#if defined(INET) && defined(INET6)
|
||||||
net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
|
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 {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We increment here since
|
* 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
|
* the locked tcb (last argument) is NOT a
|
||||||
* TCB.. aka NULL.
|
* TCB.. aka NULL.
|
||||||
*/
|
*/
|
||||||
|
net = NULL;
|
||||||
SCTP_INP_INCR_REF(inp);
|
SCTP_INP_INCR_REF(inp);
|
||||||
stcb = sctp_findassociation_ep_addr(&inp,
|
stcb = sctp_findassociation_ep_addr(&inp, addr,
|
||||||
(struct sockaddr *)&paddrp->spp_address,
|
|
||||||
&net, NULL, NULL);
|
&net, NULL, NULL);
|
||||||
if (stcb == NULL) {
|
if (stcb == NULL) {
|
||||||
SCTP_INP_DECR_REF(inp);
|
SCTP_INP_DECR_REF(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb && (net == NULL)) {
|
if ((stcb != NULL) && (net == NULL)) {
|
||||||
struct sockaddr *sa;
|
|
||||||
|
|
||||||
sa = (struct sockaddr *)&paddrp->spp_address;
|
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
if (sa->sa_family == AF_INET) {
|
if (addr->sa_family == AF_INET) {
|
||||||
|
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
sin = (struct sockaddr_in *)sa;
|
sin = (struct sockaddr_in *)addr;
|
||||||
if (sin->sin_addr.s_addr) {
|
if (sin->sin_addr.s_addr != INADDR_ANY) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
@ -4987,10 +5123,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
if (sa->sa_family == AF_INET6) {
|
if (addr->sa_family == AF_INET6) {
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *)sa;
|
sin6 = (struct sockaddr_in6 *)addr;
|
||||||
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
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);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
if (stcb) {
|
if (stcb != NULL) {
|
||||||
/************************TCB SPECIFIC SET ******************/
|
/************************TCB SPECIFIC SET ******************/
|
||||||
/*
|
/*
|
||||||
* do we change the timer for HB, we run
|
* 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 ? */
|
/* network sets ? */
|
||||||
if (net) {
|
if (net != NULL) {
|
||||||
/************************NET SPECIFIC SET ******************/
|
/************************NET SPECIFIC SET ******************/
|
||||||
if (paddrp->spp_flags & SPP_HB_DISABLE) {
|
if (paddrp->spp_flags & SPP_HB_DISABLE) {
|
||||||
if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
|
if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
|
||||||
@ -5119,7 +5255,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/
|
/************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/
|
||||||
if (paddrp->spp_pathmaxrxt) {
|
if (paddrp->spp_pathmaxrxt != 0) {
|
||||||
stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt;
|
stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt;
|
||||||
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
||||||
if (net->dest_state & SCTP_ADDR_PF) {
|
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_flags & SPP_HB_ENABLE) {
|
||||||
if (paddrp->spp_hbinterval) {
|
if (paddrp->spp_hbinterval != 0) {
|
||||||
stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval;
|
stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval;
|
||||||
} else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
|
} else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
|
||||||
stcb->asoc.heart_beat_delay = 0;
|
stcb->asoc.heart_beat_delay = 0;
|
||||||
}
|
}
|
||||||
/* Turn back on the timer */
|
/* Turn back on the timer */
|
||||||
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
||||||
if (paddrp->spp_hbinterval) {
|
if (paddrp->spp_hbinterval != 0) {
|
||||||
net->heart_beat_delay = paddrp->spp_hbinterval;
|
net->heart_beat_delay = paddrp->spp_hbinterval;
|
||||||
} else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
|
} else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
|
||||||
net->heart_beat_delay = 0;
|
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
|
* set it with the options on the
|
||||||
* socket
|
* socket
|
||||||
*/
|
*/
|
||||||
if (paddrp->spp_pathmaxrxt) {
|
if (paddrp->spp_pathmaxrxt != 0) {
|
||||||
inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt;
|
inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt;
|
||||||
}
|
}
|
||||||
if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO)
|
if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO)
|
||||||
inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0;
|
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)
|
if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL)
|
||||||
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);
|
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_setprim *spa;
|
||||||
struct sctp_nets *net;
|
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_CHECK_AND_CAST(spa, optval, struct sctp_setprim, optsize);
|
||||||
SCTP_FIND_STCB(inp, stcb, spa->ssp_assoc_id);
|
SCTP_FIND_STCB(inp, stcb, spa->ssp_assoc_id);
|
||||||
|
|
||||||
net = NULL;
|
#if defined(INET) && defined(INET6)
|
||||||
if (stcb) {
|
if (spa->ssp_addr.ss_family == AF_INET6) {
|
||||||
net = sctp_findnet(stcb, (struct sockaddr *)&spa->ssp_addr);
|
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 {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We increment here since
|
* 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
|
* the locked tcb (last argument) is NOT a
|
||||||
* TCB.. aka NULL.
|
* TCB.. aka NULL.
|
||||||
*/
|
*/
|
||||||
|
net = NULL;
|
||||||
SCTP_INP_INCR_REF(inp);
|
SCTP_INP_INCR_REF(inp);
|
||||||
stcb = sctp_findassociation_ep_addr(&inp,
|
stcb = sctp_findassociation_ep_addr(&inp, addr,
|
||||||
(struct sockaddr *)&spa->ssp_addr,
|
|
||||||
&net, NULL, NULL);
|
&net, NULL, NULL);
|
||||||
if (stcb == NULL) {
|
if (stcb == NULL) {
|
||||||
SCTP_INP_DECR_REF(inp);
|
SCTP_INP_DECR_REF(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((stcb) && (net)) {
|
if ((stcb != NULL) && (net != NULL)) {
|
||||||
if ((net != stcb->asoc.primary_destination) &&
|
if ((net != stcb->asoc.primary_destination) &&
|
||||||
(!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) {
|
(!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) {
|
||||||
/* Ok we need to set it */
|
/* 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);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
}
|
}
|
||||||
if (stcb) {
|
if (stcb != NULL) {
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -5472,14 +5630,36 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
case SCTP_SET_PEER_PRIMARY_ADDR:
|
case SCTP_SET_PEER_PRIMARY_ADDR:
|
||||||
{
|
{
|
||||||
struct sctp_setpeerprim *sspp;
|
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_CHECK_AND_CAST(sspp, optval, struct sctp_setpeerprim, optsize);
|
||||||
SCTP_FIND_STCB(inp, stcb, sspp->sspp_assoc_id);
|
SCTP_FIND_STCB(inp, stcb, sspp->sspp_assoc_id);
|
||||||
if (stcb != NULL) {
|
if (stcb != NULL) {
|
||||||
struct sctp_ifa *ifa;
|
struct sctp_ifa *ifa;
|
||||||
|
|
||||||
ifa = sctp_find_ifa_by_addr((struct sockaddr *)&sspp->sspp_addr,
|
#if defined(INET) && defined(INET6)
|
||||||
stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
|
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) {
|
if (ifa == NULL) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
@ -5510,13 +5690,13 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
goto out_of_it;
|
goto out_of_it;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (sspp->sspp_addr.ss_family) {
|
switch (addr->sa_family) {
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
{
|
{
|
||||||
struct sockaddr_in *sin;
|
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,
|
if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
|
||||||
&sin->sin_addr) != 0) {
|
&sin->sin_addr) != 0) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
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;
|
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,
|
if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
|
||||||
&sin6->sin6_addr) != 0) {
|
&sin6->sin6_addr) != 0) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
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;
|
goto out_of_it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sctp_set_primary_ip_address_sa(stcb,
|
if (sctp_set_primary_ip_address_sa(stcb, addr) != 0) {
|
||||||
(struct sockaddr *)&sspp->sspp_addr) != 0) {
|
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||||
error = 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_paddrthlds *thlds;
|
||||||
struct sctp_nets *net;
|
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_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, optsize);
|
||||||
SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
|
SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
|
||||||
net = NULL;
|
|
||||||
if (stcb) {
|
#if defined(INET) && defined(INET6)
|
||||||
net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address);
|
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 {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We increment here since
|
* 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
|
* the locked tcb (last argument) is NOT a
|
||||||
* TCB.. aka NULL.
|
* TCB.. aka NULL.
|
||||||
*/
|
*/
|
||||||
|
net = NULL;
|
||||||
SCTP_INP_INCR_REF(inp);
|
SCTP_INP_INCR_REF(inp);
|
||||||
stcb = sctp_findassociation_ep_addr(&inp,
|
stcb = sctp_findassociation_ep_addr(&inp, addr,
|
||||||
(struct sockaddr *)&thlds->spt_address,
|
|
||||||
&net, NULL, NULL);
|
&net, NULL, NULL);
|
||||||
if (stcb == NULL) {
|
if (stcb == NULL) {
|
||||||
SCTP_INP_DECR_REF(inp);
|
SCTP_INP_DECR_REF(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb && (net == NULL)) {
|
if ((stcb != NULL) && (net == NULL)) {
|
||||||
struct sockaddr *sa;
|
|
||||||
|
|
||||||
sa = (struct sockaddr *)&thlds->spt_address;
|
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
if (sa->sa_family == AF_INET) {
|
if (addr->sa_family == AF_INET) {
|
||||||
|
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
sin = (struct sockaddr_in *)sa;
|
sin = (struct sockaddr_in *)addr;
|
||||||
if (sin->sin_addr.s_addr) {
|
if (sin->sin_addr.s_addr != INADDR_ANY) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
@ -5940,10 +6139,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
if (sa->sa_family == AF_INET6) {
|
if (addr->sa_family == AF_INET6) {
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *)sa;
|
sin6 = (struct sockaddr_in6 *)addr;
|
||||||
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
@ -5959,8 +6158,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb) {
|
if (stcb != NULL) {
|
||||||
if (net) {
|
if (net != NULL) {
|
||||||
if (net->dest_state & SCTP_ADDR_PF) {
|
if (net->dest_state & SCTP_ADDR_PF) {
|
||||||
if ((net->failure_threshold > thlds->spt_pathmaxrxt) ||
|
if ((net->failure_threshold > thlds->spt_pathmaxrxt) ||
|
||||||
(net->failure_threshold <= thlds->spt_pathpfthld)) {
|
(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_udpencaps *encaps;
|
||||||
struct sctp_nets *net;
|
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_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, optsize);
|
||||||
SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id);
|
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 {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We increment here since
|
* We increment here since
|
||||||
@ -6055,22 +6278,19 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
*/
|
*/
|
||||||
net = NULL;
|
net = NULL;
|
||||||
SCTP_INP_INCR_REF(inp);
|
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) {
|
if (stcb == NULL) {
|
||||||
SCTP_INP_DECR_REF(inp);
|
SCTP_INP_DECR_REF(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb && (net == NULL)) {
|
if ((stcb != NULL) && (net == NULL)) {
|
||||||
struct sockaddr *sa;
|
|
||||||
|
|
||||||
sa = (struct sockaddr *)&encaps->sue_address;
|
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
if (sa->sa_family == AF_INET) {
|
if (addr->sa_family == AF_INET) {
|
||||||
|
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
sin = (struct sockaddr_in *)sa;
|
sin = (struct sockaddr_in *)addr;
|
||||||
if (sin->sin_addr.s_addr) {
|
if (sin->sin_addr.s_addr != INADDR_ANY) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
@ -6079,10 +6299,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
if (sa->sa_family == AF_INET6) {
|
if (addr->sa_family == AF_INET6) {
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *)sa;
|
sin6 = (struct sockaddr_in6 *)addr;
|
||||||
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||||
SCTP_TCB_UNLOCK(stcb);
|
SCTP_TCB_UNLOCK(stcb);
|
||||||
@ -6098,8 +6318,8 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stcb) {
|
if (stcb != NULL) {
|
||||||
if (net) {
|
if (net != NULL) {
|
||||||
net->port = encaps->sue_port;
|
net->port = encaps->sue_port;
|
||||||
} else {
|
} else {
|
||||||
stcb->asoc.port = encaps->sue_port;
|
stcb->asoc.port = encaps->sue_port;
|
||||||
|
@ -2760,7 +2760,16 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
|
|||||||
switch (sa->sa_family) {
|
switch (sa->sa_family) {
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
case AF_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));
|
memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
@ -5653,43 +5662,43 @@ sctp_sorecvmsg(struct socket *so,
|
|||||||
entry->flgs = control->sinfo_flags;
|
entry->flgs = control->sinfo_flags;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (fromlen && from) {
|
if ((fromlen > 0) && (from != NULL)) {
|
||||||
cp_len = min((size_t)fromlen, (size_t)control->whoFrom->ro._l_addr.sa.sa_len);
|
union sctp_sockstore store;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
switch (control->whoFrom->ro._l_addr.sa.sa_family) {
|
switch (control->whoFrom->ro._l_addr.sa.sa_family) {
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
case AF_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;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
case AF_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;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
len = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
memcpy(from, &control->whoFrom->ro._l_addr, cp_len);
|
memcpy(from, &store, min((size_t)fromlen, 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
|
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 lsa6, *from6;
|
struct sockaddr_in6 lsa6, *from6;
|
||||||
@ -6450,7 +6459,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
|
|||||||
{
|
{
|
||||||
struct sockaddr *addr_touse;
|
struct sockaddr *addr_touse;
|
||||||
|
|
||||||
#ifdef INET6
|
#if defined(INET) && defined(INET6)
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -6464,8 +6473,10 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
|
|||||||
addr_touse = sa;
|
addr_touse = sa;
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
if (sa->sa_family == AF_INET6) {
|
if (sa->sa_family == AF_INET6) {
|
||||||
|
#ifdef INET
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
|
|
||||||
|
#endif
|
||||||
if (sa->sa_len != sizeof(struct sockaddr_in6)) {
|
if (sa->sa_len != sizeof(struct sockaddr_in6)) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
|
||||||
*error = EINVAL;
|
*error = EINVAL;
|
||||||
@ -6477,6 +6488,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
|
|||||||
*error = EINVAL;
|
*error = EINVAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef INET
|
||||||
sin6 = (struct sockaddr_in6 *)addr_touse;
|
sin6 = (struct sockaddr_in6 *)addr_touse;
|
||||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
|
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);
|
in6_sin6_2_sin(&sin, sin6);
|
||||||
addr_touse = (struct sockaddr *)&sin;
|
addr_touse = (struct sockaddr *)&sin;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
@ -6578,7 +6591,7 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
|
|||||||
{
|
{
|
||||||
struct sockaddr *addr_touse;
|
struct sockaddr *addr_touse;
|
||||||
|
|
||||||
#ifdef INET6
|
#if defined(INET) && defined(INET6)
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -6592,8 +6605,11 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
|
|||||||
addr_touse = sa;
|
addr_touse = sa;
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
if (sa->sa_family == AF_INET6) {
|
if (sa->sa_family == AF_INET6) {
|
||||||
|
#ifdef INET
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sa->sa_len != sizeof(struct sockaddr_in6)) {
|
if (sa->sa_len != sizeof(struct sockaddr_in6)) {
|
||||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
|
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
|
||||||
*error = EINVAL;
|
*error = EINVAL;
|
||||||
@ -6605,6 +6621,7 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
|
|||||||
*error = EINVAL;
|
*error = EINVAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef INET
|
||||||
sin6 = (struct sockaddr_in6 *)addr_touse;
|
sin6 = (struct sockaddr_in6 *)addr_touse;
|
||||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
|
||||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
|
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);
|
in6_sin6_2_sin(&sin, sin6);
|
||||||
addr_touse = (struct sockaddr *)&sin;
|
addr_touse = (struct sockaddr *)&sin;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
|
@ -216,10 +216,10 @@ udp_init(void)
|
|||||||
* a 4-tuple, flip this to 4-tuple.
|
* a 4-tuple, flip this to 4-tuple.
|
||||||
*/
|
*/
|
||||||
in_pcbinfo_init(&V_udbinfo, "udp", &V_udb, UDBHASHSIZE, UDBHASHSIZE,
|
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);
|
IPI_HASHFIELDS_2TUPLE);
|
||||||
V_udpcb_zone = uma_zcreate("udpcb", sizeof(struct udpcb),
|
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_max(V_udpcb_zone, maxsockets);
|
||||||
uma_zone_set_warning(V_udpcb_zone, "kern.ipc.maxsockets limit reached");
|
uma_zone_set_warning(V_udpcb_zone, "kern.ipc.maxsockets limit reached");
|
||||||
EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL,
|
EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL,
|
||||||
@ -232,7 +232,7 @@ udplite_init(void)
|
|||||||
|
|
||||||
in_pcbinfo_init(&V_ulitecbinfo, "udplite", &V_ulitecb, UDBHASHSIZE,
|
in_pcbinfo_init(&V_ulitecbinfo, "udplite", &V_ulitecb, UDBHASHSIZE,
|
||||||
UDBHASHSIZE, "udplite_inpcb", udplite_inpcb_init, NULL,
|
UDBHASHSIZE, "udplite_inpcb", udplite_inpcb_init, NULL,
|
||||||
UMA_ZONE_NOFREE, IPI_HASHFIELDS_2TUPLE);
|
0, IPI_HASHFIELDS_2TUPLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2313,7 +2313,8 @@ key_spdacquire(struct secpolicy *sp)
|
|||||||
} else {
|
} else {
|
||||||
/* increment counter and do nothing. */
|
/* increment counter and do nothing. */
|
||||||
newspacq->count++;
|
newspacq->count++;
|
||||||
return 0;
|
SPACQ_UNLOCK();
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
SPACQ_UNLOCK();
|
SPACQ_UNLOCK();
|
||||||
} else {
|
} else {
|
||||||
|
@ -39,15 +39,6 @@ struct vattr;
|
|||||||
struct vnode;
|
struct vnode;
|
||||||
struct reg;
|
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 *);
|
int dtrace_trap(struct trapframe *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -81,7 +81,6 @@
|
|||||||
#define P_OSREL_SIGSEGV 700004
|
#define P_OSREL_SIGSEGV 700004
|
||||||
#define P_OSREL_MAP_ANON 800104
|
#define P_OSREL_MAP_ANON 800104
|
||||||
#define P_OSREL_MAP_FSTRICT 1100036
|
#define P_OSREL_MAP_FSTRICT 1100036
|
||||||
#define P_OSREL_MAP_RENAME 1100039
|
|
||||||
|
|
||||||
#define P_OSREL_MAJOR(x) ((x) / 100000)
|
#define P_OSREL_MAJOR(x) ((x) / 100000)
|
||||||
#endif
|
#endif
|
||||||
|
@ -222,8 +222,7 @@ sys_mmap(td, uap)
|
|||||||
/*
|
/*
|
||||||
* Ignore old flags that used to be defined but did not do anything.
|
* 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.
|
* Enforce the constraints.
|
||||||
|
@ -468,7 +468,12 @@ vm_object_vndeallocate(vm_object_t object)
|
|||||||
}
|
}
|
||||||
#endif
|
#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--;
|
object->ref_count--;
|
||||||
VM_OBJECT_WUNLOCK(object);
|
VM_OBJECT_WUNLOCK(object);
|
||||||
/* vrele may need the vnode lock. */
|
/* vrele may need the vnode lock. */
|
||||||
|
@ -4,7 +4,7 @@ PROG= iscsictl
|
|||||||
SRCS= iscsictl.c periphs.c parse.y token.l y.tab.h
|
SRCS= iscsictl.c periphs.c parse.y token.l y.tab.h
|
||||||
CFLAGS+= -I${.CURDIR}
|
CFLAGS+= -I${.CURDIR}
|
||||||
CFLAGS+= -I${.CURDIR}/../../sys/dev/iscsi
|
CFLAGS+= -I${.CURDIR}/../../sys/dev/iscsi
|
||||||
MAN= iscsictl.8
|
MAN= iscsi.conf.5 iscsictl.8
|
||||||
|
|
||||||
LIBADD= cam util
|
LIBADD= cam util
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* -C option added in 1998, original code by Marc Espie, based on FreeBSD
|
* -C option added in 1998, original code by Marc Espie, based on FreeBSD
|
||||||
* behaviour
|
* 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$
|
* $FreeBSD$
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -150,8 +150,8 @@ main(int argc, char *argv[])
|
|||||||
const char *tmpdir;
|
const char *tmpdir;
|
||||||
char *v;
|
char *v;
|
||||||
|
|
||||||
setlinebuf(stdout);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
setlinebuf(stderr);
|
setvbuf(stderr, NULL, _IOLBF, 0);
|
||||||
for (i = 0; i < MAXFILEC; i++)
|
for (i = 0; i < MAXFILEC; i++)
|
||||||
filearg[i] = NULL;
|
filearg[i] = NULL;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
* -C option added in 1998, original code by Marc Espie, based on FreeBSD
|
* -C option added in 1998, original code by Marc Espie, based on FreeBSD
|
||||||
* behaviour
|
* 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$
|
* $FreeBSD$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
/* Patch (diff listing) abstract type. */
|
/* 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_first; /* 1st line number */
|
||||||
static LINENUM p_newfirst; /* 1st line number of replacement */
|
static LINENUM p_newfirst; /* 1st line number of replacement */
|
||||||
static LINENUM p_ptrn_lines; /* # lines in pattern */
|
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 char *p_char = NULL; /* +, -, and ! */
|
||||||
static int hunkmax = INITHUNKMAX; /* size of above arrays to begin with */
|
static int hunkmax = INITHUNKMAX; /* size of above arrays to begin with */
|
||||||
static int p_indent; /* indent to patch */
|
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_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_sline; /* and the line number for it */
|
||||||
static LINENUM p_hunk_beg; /* line number of current hunk */
|
static LINENUM p_hunk_beg; /* line number of current hunk */
|
||||||
static LINENUM p_efake = -1; /* end of faked up lines--don't free */
|
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 void grow_hunkmax(void);
|
||||||
static int intuit_diff_type(void);
|
static int intuit_diff_type(void);
|
||||||
static void next_intuit_at(LINENUM, LINENUM);
|
static void next_intuit_at(off_t, LINENUM);
|
||||||
static void skip_to(LINENUM, LINENUM);
|
static void skip_to(off_t, LINENUM);
|
||||||
static size_t pgets(bool _do_indent);
|
static size_t pgets(bool _do_indent);
|
||||||
static char *best_name(const struct file_name *, bool);
|
static char *best_name(const struct file_name *, bool);
|
||||||
static char *posix_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");
|
pfp = fopen(filename, "r");
|
||||||
if (pfp == NULL)
|
if (pfp == NULL)
|
||||||
pfatal("patch file %s not found", filename);
|
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;
|
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();
|
set_hunkmax();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +173,7 @@ there_is_another_patch(void)
|
|||||||
{
|
{
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
|
|
||||||
if (p_base != 0L && p_base >= p_filesize) {
|
if (p_base != 0 && p_base >= p_filesize) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
say("done\n");
|
say("done\n");
|
||||||
return false;
|
return false;
|
||||||
@ -181,7 +182,7 @@ there_is_another_patch(void)
|
|||||||
say("Hmm...");
|
say("Hmm...");
|
||||||
diff_type = intuit_diff_type();
|
diff_type = intuit_diff_type();
|
||||||
if (!diff_type) {
|
if (!diff_type) {
|
||||||
if (p_base != 0L) {
|
if (p_base != 0) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
say(" Ignoring the trailing garbage.\ndone\n");
|
say(" Ignoring the trailing garbage.\ndone\n");
|
||||||
} else
|
} else
|
||||||
@ -190,7 +191,7 @@ there_is_another_patch(void)
|
|||||||
}
|
}
|
||||||
if (verbose)
|
if (verbose)
|
||||||
say(" %sooks like %s to me...\n",
|
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 == UNI_DIFF ? "a unified diff" :
|
||||||
diff_type == CONTEXT_DIFF ? "a context diff" :
|
diff_type == CONTEXT_DIFF ? "a context diff" :
|
||||||
diff_type == NEW_CONTEXT_DIFF ? "a new-style 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
|
static int
|
||||||
intuit_diff_type(void)
|
intuit_diff_type(void)
|
||||||
{
|
{
|
||||||
long this_line = 0, previous_line;
|
off_t this_line = 0, previous_line;
|
||||||
long first_command_line = -1;
|
off_t first_command_line = -1;
|
||||||
LINENUM fcl_line = -1;
|
LINENUM fcl_line = -1;
|
||||||
bool last_line_was_command = false, this_is_a_command = false;
|
bool last_line_was_command = false, this_is_a_command = false;
|
||||||
bool stars_last_line = false, stars_this_line = false;
|
bool stars_last_line = false, stars_this_line = false;
|
||||||
@ -263,17 +264,17 @@ intuit_diff_type(void)
|
|||||||
|
|
||||||
memset(names, 0, sizeof(names));
|
memset(names, 0, sizeof(names));
|
||||||
ok_to_create_file = false;
|
ok_to_create_file = false;
|
||||||
fseek(pfp, p_base, SEEK_SET);
|
fseeko(pfp, p_base, SEEK_SET);
|
||||||
p_input_line = p_bline - 1;
|
p_input_line = p_bline - 1;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
previous_line = this_line;
|
previous_line = this_line;
|
||||||
last_line_was_command = this_is_a_command;
|
last_line_was_command = this_is_a_command;
|
||||||
stars_last_line = stars_this_line;
|
stars_last_line = stars_this_line;
|
||||||
this_line = ftell(pfp);
|
this_line = ftello(pfp);
|
||||||
indent = 0;
|
indent = 0;
|
||||||
p_input_line++;
|
p_input_line++;
|
||||||
if (pgets(false) == 0) {
|
if (pgets(false) == 0) {
|
||||||
if (first_command_line >= 0L) {
|
if (first_command_line >= 0) {
|
||||||
/* nothing but deletes!? */
|
/* nothing but deletes!? */
|
||||||
p_start = first_command_line;
|
p_start = first_command_line;
|
||||||
p_sline = fcl_line;
|
p_sline = fcl_line;
|
||||||
@ -296,7 +297,7 @@ intuit_diff_type(void)
|
|||||||
;
|
;
|
||||||
this_is_a_command = (isdigit((unsigned char)*s) &&
|
this_is_a_command = (isdigit((unsigned char)*s) &&
|
||||||
(*t == 'd' || *t == 'c' || *t == 'a'));
|
(*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;
|
first_command_line = this_line;
|
||||||
fcl_line = p_input_line;
|
fcl_line = p_input_line;
|
||||||
p_indent = indent; /* assume this for now */
|
p_indent = indent; /* assume this for now */
|
||||||
@ -318,7 +319,8 @@ intuit_diff_type(void)
|
|||||||
for (t = s + 7; isspace((unsigned char)*t); t++)
|
for (t = s + 7; isspace((unsigned char)*t); t++)
|
||||||
;
|
;
|
||||||
revision = savestr(t);
|
revision = savestr(t);
|
||||||
for (t = revision; *t && !isspace((unsigned char)*t); t++)
|
for (t = revision;
|
||||||
|
*t && !isspace((unsigned char)*t); t++)
|
||||||
;
|
;
|
||||||
*t = '\0';
|
*t = '\0';
|
||||||
if (*revision == '\0') {
|
if (*revision == '\0') {
|
||||||
@ -332,7 +334,7 @@ intuit_diff_type(void)
|
|||||||
p4_fetchname(&names[OLD_FILE], s + 5);
|
p4_fetchname(&names[OLD_FILE], s + 5);
|
||||||
}
|
}
|
||||||
if ((!diff_type || diff_type == ED_DIFF) &&
|
if ((!diff_type || diff_type == ED_DIFF) &&
|
||||||
first_command_line >= 0L &&
|
first_command_line >= 0 &&
|
||||||
strEQ(s, ".\n")) {
|
strEQ(s, ".\n")) {
|
||||||
p_indent = indent;
|
p_indent = indent;
|
||||||
p_start = first_command_line;
|
p_start = first_command_line;
|
||||||
@ -356,9 +358,9 @@ intuit_diff_type(void)
|
|||||||
ok_to_create_file = true;
|
ok_to_create_file = true;
|
||||||
/*
|
/*
|
||||||
* If this is a new context diff the character just
|
* 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++;
|
s++;
|
||||||
p_indent = indent;
|
p_indent = indent;
|
||||||
p_start = previous_line;
|
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.
|
* Remember where this patch ends so we know where to start up again.
|
||||||
*/
|
*/
|
||||||
static void
|
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_base = file_pos;
|
||||||
p_bline = file_line;
|
p_bline = file_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basically a verbose fseek() to the actual diff listing.
|
* Basically a verbose fseeko() to the actual diff listing.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
skip_to(LINENUM file_pos, LINENUM file_line)
|
skip_to(off_t file_pos, LINENUM file_line)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (p_base > file_pos)
|
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) {
|
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");
|
say("The text leading up to this was:\n--------------------------\n");
|
||||||
while (ftell(pfp) < file_pos) {
|
while (ftello(pfp) < file_pos) {
|
||||||
len = pgets(false);
|
len = pgets(false);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
fatal("Unexpected end of file\n");
|
fatal("Unexpected end of file\n");
|
||||||
@ -449,7 +452,7 @@ skip_to(LINENUM file_pos, LINENUM file_line)
|
|||||||
}
|
}
|
||||||
say("--------------------------\n");
|
say("--------------------------\n");
|
||||||
} else
|
} else
|
||||||
fseek(pfp, file_pos, SEEK_SET);
|
fseeko(pfp, file_pos, SEEK_SET);
|
||||||
p_input_line = file_line - 1;
|
p_input_line = file_line - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,7 +482,7 @@ remove_special_line(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (c != EOF)
|
if (c != EOF)
|
||||||
fseek(pfp, -1L, SEEK_CUR);
|
fseeko(pfp, -1, SEEK_CUR);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -490,7 +493,7 @@ remove_special_line(void)
|
|||||||
bool
|
bool
|
||||||
another_hunk(void)
|
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 repl_beginning; /* index of --- line */
|
||||||
LINENUM fillcnt; /* #lines of missing ptrn or repl */
|
LINENUM fillcnt; /* #lines of missing ptrn or repl */
|
||||||
LINENUM fillsrc; /* index of first line to copy */
|
LINENUM fillsrc; /* index of first line to copy */
|
||||||
@ -498,7 +501,7 @@ another_hunk(void)
|
|||||||
bool ptrn_spaces_eaten; /* ptrn was slightly misformed */
|
bool ptrn_spaces_eaten; /* ptrn was slightly misformed */
|
||||||
bool repl_could_be_missing; /* no + or ! lines in this hunk */
|
bool repl_could_be_missing; /* no + or ! lines in this hunk */
|
||||||
bool repl_missing; /* we are now backtracking */
|
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 repl_patch_line; /* input line number for same */
|
||||||
LINENUM ptrn_copiable; /* # of copiable lines in ptrn */
|
LINENUM ptrn_copiable; /* # of copiable lines in ptrn */
|
||||||
char *s;
|
char *s;
|
||||||
@ -516,7 +519,7 @@ another_hunk(void)
|
|||||||
|
|
||||||
p_max = hunkmax; /* gets reduced when --- found */
|
p_max = hunkmax; /* gets reduced when --- found */
|
||||||
if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) {
|
if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) {
|
||||||
line_beginning = ftell(pfp);
|
line_beginning = ftello(pfp);
|
||||||
repl_beginning = 0;
|
repl_beginning = 0;
|
||||||
fillcnt = 0;
|
fillcnt = 0;
|
||||||
fillsrc = 0;
|
fillsrc = 0;
|
||||||
@ -537,7 +540,7 @@ another_hunk(void)
|
|||||||
p_context = 100;
|
p_context = 100;
|
||||||
p_hunk_beg = p_input_line + 1;
|
p_hunk_beg = p_input_line + 1;
|
||||||
while (p_end < p_max) {
|
while (p_end < p_max) {
|
||||||
line_beginning = ftell(pfp);
|
line_beginning = ftello(pfp);
|
||||||
len = pgets(true);
|
len = pgets(true);
|
||||||
p_input_line++;
|
p_input_line++;
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
@ -583,7 +586,8 @@ another_hunk(void)
|
|||||||
p_end--;
|
p_end--;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (s = buf; *s && !isdigit((unsigned char)*s); s++)
|
for (s = buf;
|
||||||
|
*s && !isdigit((unsigned char)*s); s++)
|
||||||
;
|
;
|
||||||
if (!*s)
|
if (!*s)
|
||||||
malformed();
|
malformed();
|
||||||
@ -593,7 +597,8 @@ another_hunk(void)
|
|||||||
while (isdigit((unsigned char)*s))
|
while (isdigit((unsigned char)*s))
|
||||||
s++;
|
s++;
|
||||||
if (*s == ',') {
|
if (*s == ',') {
|
||||||
for (; *s && !isdigit((unsigned char)*s); s++)
|
for (;
|
||||||
|
*s && !isdigit((unsigned char)*s); s++)
|
||||||
;
|
;
|
||||||
if (!*s)
|
if (!*s)
|
||||||
malformed();
|
malformed();
|
||||||
@ -644,7 +649,7 @@ another_hunk(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
repl_beginning = p_end;
|
repl_beginning = p_end;
|
||||||
repl_backtrack_position = ftell(pfp);
|
repl_backtrack_position = ftello(pfp);
|
||||||
repl_patch_line = p_input_line;
|
repl_patch_line = p_input_line;
|
||||||
p_line[p_end] = savestr(buf);
|
p_line[p_end] = savestr(buf);
|
||||||
if (out_of_mem) {
|
if (out_of_mem) {
|
||||||
@ -690,8 +695,8 @@ another_hunk(void)
|
|||||||
change_line:
|
change_line:
|
||||||
if (buf[1] == '\n' && canonicalize)
|
if (buf[1] == '\n' && canonicalize)
|
||||||
strlcpy(buf + 1, " \n", buf_size - 1);
|
strlcpy(buf + 1, " \n", buf_size - 1);
|
||||||
if (!isspace((unsigned char)buf[1]) && buf[1] != '>' &&
|
if (!isspace((unsigned char)buf[1]) &&
|
||||||
buf[1] != '<' &&
|
buf[1] != '>' && buf[1] != '<' &&
|
||||||
repl_beginning && repl_could_be_missing) {
|
repl_beginning && repl_could_be_missing) {
|
||||||
repl_missing = true;
|
repl_missing = true;
|
||||||
goto hunk_done;
|
goto hunk_done;
|
||||||
@ -776,7 +781,7 @@ another_hunk(void)
|
|||||||
p_input_line = repl_patch_line;
|
p_input_line = repl_patch_line;
|
||||||
for (p_end--; p_end > repl_beginning; p_end--)
|
for (p_end--; p_end > repl_beginning; p_end--)
|
||||||
free(p_line[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 */
|
/* redundant 'new' context lines were omitted - set */
|
||||||
/* up to fill them in from the old file context */
|
/* up to fill them in from the old file context */
|
||||||
@ -854,7 +859,7 @@ another_hunk(void)
|
|||||||
LINENUM fillnew; /* index of new lines */
|
LINENUM fillnew; /* index of new lines */
|
||||||
char ch;
|
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);
|
len = pgets(true);
|
||||||
p_input_line++;
|
p_input_line++;
|
||||||
if (len == 0 || strnNE(buf, "@@ -", 4)) {
|
if (len == 0 || strnNE(buf, "@@ -", 4)) {
|
||||||
@ -918,7 +923,7 @@ another_hunk(void)
|
|||||||
context = 0;
|
context = 0;
|
||||||
p_hunk_beg = p_input_line + 1;
|
p_hunk_beg = p_input_line + 1;
|
||||||
while (fillold <= p_ptrn_lines || fillnew <= p_end) {
|
while (fillold <= p_ptrn_lines || fillnew <= p_end) {
|
||||||
line_beginning = ftell(pfp);
|
line_beginning = ftello(pfp);
|
||||||
len = pgets(true);
|
len = pgets(true);
|
||||||
p_input_line++;
|
p_input_line++;
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
@ -1021,7 +1026,7 @@ another_hunk(void)
|
|||||||
int i;
|
int i;
|
||||||
LINENUM min, max;
|
LINENUM min, max;
|
||||||
|
|
||||||
line_beginning = ftell(pfp);
|
line_beginning = ftello(pfp);
|
||||||
p_context = 0;
|
p_context = 0;
|
||||||
len = pgets(true);
|
len = pgets(true);
|
||||||
p_input_line++;
|
p_input_line++;
|
||||||
@ -1398,7 +1403,7 @@ void
|
|||||||
do_ed_script(void)
|
do_ed_script(void)
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
long beginning_of_this_line;
|
off_t beginning_of_this_line;
|
||||||
FILE *pipefp = NULL;
|
FILE *pipefp = NULL;
|
||||||
|
|
||||||
if (!skip_rest_of_patch) {
|
if (!skip_rest_of_patch) {
|
||||||
@ -1411,7 +1416,7 @@ do_ed_script(void)
|
|||||||
pipefp = popen(buf, "w");
|
pipefp = popen(buf, "w");
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
beginning_of_this_line = ftell(pfp);
|
beginning_of_this_line = ftello(pfp);
|
||||||
if (pgets(true) == 0) {
|
if (pgets(true) == 0) {
|
||||||
next_intuit_at(beginning_of_this_line, p_input_line);
|
next_intuit_at(beginning_of_this_line, p_input_line);
|
||||||
break;
|
break;
|
||||||
@ -1420,8 +1425,8 @@ do_ed_script(void)
|
|||||||
for (t = buf; isdigit((unsigned char)*t) || *t == ','; t++)
|
for (t = buf; isdigit((unsigned char)*t) || *t == ','; t++)
|
||||||
;
|
;
|
||||||
/* POSIX defines allowed commands as {a,c,d,i,s} */
|
/* POSIX defines allowed commands as {a,c,d,i,s} */
|
||||||
if (isdigit((unsigned char)*buf) && (*t == 'a' || *t == 'c' ||
|
if (isdigit((unsigned char)*buf) &&
|
||||||
*t == 'd' || *t == 'i' || *t == 's')) {
|
(*t == 'a' || *t == 'c' || *t == 'd' || *t == 'i' || *t == 's')) {
|
||||||
if (pipefp != NULL)
|
if (pipefp != NULL)
|
||||||
fputs(buf, pipefp);
|
fputs(buf, pipefp);
|
||||||
if (*t != 'd') {
|
if (*t != 'd') {
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
.\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
|
.\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd December 4, 2014
|
.Dd December 6, 2014
|
||||||
.Dt CTLADM 8
|
.Dt CTLADM 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.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.
|
client through the selection of appropriate commands and task attributes.
|
||||||
The default value is "restricted". It improves data integrity, but may
|
The default value is "restricted". It improves data integrity, but may
|
||||||
introduce some additional delays.
|
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
|
.It Va rpm
|
||||||
Specifies medium rotation rate of the device: 0 -- not reported,
|
Specifies medium rotation rate of the device: 0 -- not reported,
|
||||||
1 -- non-rotating (SSD), >1024 -- value in revolutions per minute.
|
1 -- non-rotating (SSD), >1024 -- value in revolutions per minute.
|
||||||
|
Loading…
Reference in New Issue
Block a user