Add network QoS support for PCP to iscsi initiator.

Make the Ethernet PCP codepoint configurable
for L2 local traffic, to allow lower latency for
iSCSI block IO. This addresses the initiator
side only.

Reviewed by:	mav, trasz, bcr
Sponsored by:	NetApp, Inc.
Differential Revision:	https://reviews.freebsd.org/D26739
This commit is contained in:
Richard Scheffenegger 2020-10-24 21:07:13 +00:00
parent 8b220f8915
commit 4dfbcffbb9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=367023
7 changed files with 60 additions and 1 deletions

View File

@ -71,7 +71,8 @@ struct iscsi_session_conf {
char isc_offload[ISCSI_OFFLOAD_LEN];
int isc_enable;
int isc_dscp;
int isc_spare[3];
int isc_pcp;
int isc_spare[2];
};
/*

View File

@ -155,6 +155,13 @@ and
codepoints.
Default is no specified dscp codepoint, which means the default
of the outgoing interface is used.
.It Cm pcp
The 802.1Q Priority CodePoint used for sending packets.
The PCP can be set to a value in the range between
.Qq Ar 0
to
.Qq Ar 7 .
When omitted, the default for the outgoing interface is used.
.El
.Sh FILES
.Bl -tag -width indent

View File

@ -88,6 +88,7 @@ target_new(struct conf *conf)
xo_err(1, "calloc");
targ->t_conf = conf;
targ->t_dscp = -1;
targ->t_pcp = -1;
TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next);
return (targ);
@ -360,6 +361,7 @@ conf_from_target(struct iscsi_session_conf *conf,
else
conf->isc_data_digest = ISCSI_DIGEST_NONE;
conf->isc_dscp = targ->t_dscp;
conf->isc_pcp = targ->t_pcp;
}
static int
@ -540,6 +542,9 @@ kernel_list(int iscsi_fd, const struct target *targ __unused,
if (conf->isc_dscp != -1)
xo_emit("{L:/%-26s}{V:dscp/0x%02x}\n",
"Target DSCP:", conf->isc_dscp);
if (conf->isc_pcp != -1)
xo_emit("{L:/%-26s}{V:pcp/0x%02x}\n",
"Target PCP:", conf->isc_pcp);
xo_close_container("target");
xo_open_container("auth");

View File

@ -79,6 +79,7 @@ struct target {
int t_enable;
int t_protocol;
int t_dscp;
int t_pcp;
char *t_offload;
char *t_user;
char *t_secret;

View File

@ -133,6 +133,8 @@ target_entry:
ignored
|
dscp
|
pcp
;
target_name: TARGET_NAME EQUALS STR
@ -306,6 +308,8 @@ dscp: DSCP EQUALS STR
{
uint64_t tmp;
if (target->t_dscp != -1)
xo_errx(1, "duplicated dscp at line %d", lineno);
if (strcmp($3, "0x") == 0) {
tmp = strtol($3 + 2, NULL, 16);
} else if (expand_number($3, &tmp) != 0) {
@ -344,6 +348,27 @@ dscp: DSCP EQUALS STR
| DSCP EQUALS AF43 { target->t_dscp = IPTOS_DSCP_AF43 >> 2 ; }
;
pcp: PCP EQUALS STR
{
uint64_t tmp;
if (target->t_pcp != -1)
xo_errx(1, "duplicated pcp at line %d", lineno);
if (expand_number($3, &tmp) != 0) {
yyerror("invalid numeric value");
free($3);
return(1);
}
if (!((tmp >=0) && (tmp <= 7))) {
yyerror("invalid pcp value");
return(1);
}
target->t_pcp = tmp;
}
;
%%
void

View File

@ -69,6 +69,7 @@ protocol { return PROTOCOL; }
offload { return OFFLOAD; }
port { return IGNORED; }
dscp { return DSCP; }
pcp { return PCP; }
MaxConnections { return IGNORED; }
TargetAlias { return IGNORED; }
TargetPortalGroupTag { return IGNORED; }

View File

@ -297,6 +297,25 @@ connection_new(int iscsi_fd, const struct iscsi_daemon_request *request)
from_addr);
}
}
if (conn->conn_conf.isc_pcp != -1) {
int pcp = conn->conn_conf.isc_pcp;
if (to_ai->ai_family == AF_INET) {
if (setsockopt(conn->conn_socket,
IPPROTO_IP, IP_VLAN_PCP,
&pcp, sizeof(pcp)) == -1)
log_warn("setsockopt(IP_VLAN_PCP) "
"failed for %s",
from_addr);
} else
if (to_ai->ai_family == AF_INET6) {
if (setsockopt(conn->conn_socket,
IPPROTO_IPV6, IPV6_VLAN_PCP,
&pcp, sizeof(pcp)) == -1)
log_warn("setsockopt(IPV6_VLAN_PCP) "
"failed for %s",
from_addr);
}
}
if (from_ai != NULL) {
error = bind(conn->conn_socket, from_ai->ai_addr,
from_ai->ai_addrlen);