From owner-svn-src-head@FreeBSD.ORG Thu Feb 5 06:38:04 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 11311591; Thu, 5 Feb 2015 06:38:04 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EFE057E5; Thu, 5 Feb 2015 06:38:03 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t156c3xM029270; Thu, 5 Feb 2015 06:38:03 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t156c0F6029243; Thu, 5 Feb 2015 06:38:00 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <201502050638.t156c0F6029243@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Thu, 5 Feb 2015 06:38:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r278232 - in head: sys/dev/iscsi usr.bin/iscsictl usr.sbin/iscsid X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Feb 2015 06:38:04 -0000 Author: trasz Date: Thu Feb 5 06:37:59 2015 New Revision: 278232 URL: https://svnweb.freebsd.org/changeset/base/278232 Log: Make it possible to set (via iscsi.conf(5)) and query (via iscsictl -v) initiator iSCSI offload. Pass maximum data segment size supported by chosen offload module to iscsid(8), and make iscsid(8) not try to negotiate anything larger than that. MFC after: 1 month Sponsored by: The FreeBSD Foundation Modified: head/sys/dev/iscsi/icl.h head/sys/dev/iscsi/icl_soft.c head/sys/dev/iscsi/iscsi.c head/sys/dev/iscsi/iscsi_ioctl.h head/usr.bin/iscsictl/iscsi.conf.5 head/usr.bin/iscsictl/iscsictl.c head/usr.bin/iscsictl/iscsictl.h head/usr.bin/iscsictl/parse.y head/usr.bin/iscsictl/token.l head/usr.sbin/iscsid/iscsid.c head/usr.sbin/iscsid/iscsid.h head/usr.sbin/iscsid/login.c Modified: head/sys/dev/iscsi/icl.h ============================================================================== --- head/sys/dev/iscsi/icl.h Thu Feb 5 03:56:49 2015 (r278231) +++ head/sys/dev/iscsi/icl.h Thu Feb 5 06:37:59 2015 (r278232) @@ -113,6 +113,7 @@ struct icl_conn { bool ic_disconnecting; bool ic_iser; const char *ic_name; + const char *ic_offload; void (*ic_receive)(struct icl_pdu *); void (*ic_error)(struct icl_conn *); Modified: head/sys/dev/iscsi/icl_soft.c ============================================================================== --- head/sys/dev/iscsi/icl_soft.c Thu Feb 5 03:56:49 2015 (r278231) +++ head/sys/dev/iscsi/icl_soft.c Thu Feb 5 06:37:59 2015 (r278232) @@ -1185,6 +1185,7 @@ icl_soft_new_conn(const char *name, stru #endif ic->ic_max_data_segment_length = ICL_MAX_DATA_SEGMENT_LENGTH; ic->ic_name = name; + ic->ic_offload = "none"; return (ic); } Modified: head/sys/dev/iscsi/iscsi.c ============================================================================== --- head/sys/dev/iscsi/iscsi.c Thu Feb 5 03:56:49 2015 (r278231) +++ head/sys/dev/iscsi/iscsi.c Thu Feb 5 06:37:59 2015 (r278232) @@ -1306,6 +1306,16 @@ iscsi_ioctl_daemon_wait(struct iscsi_sof request->idr_tsih = 0; /* New or reinstated session. */ memcpy(&request->idr_conf, &is->is_conf, sizeof(request->idr_conf)); + + error = icl_limits(is->is_conf.isc_offload, + &request->idr_limits.isl_max_data_segment_length); + if (error != 0) { + ISCSI_SESSION_WARN(is, "icl_limits for offload \"%s\" " + "failed with error %d", is->is_conf.isc_offload, + error); + sx_sunlock(&sc->sc_lock); + return (error); + } sx_sunlock(&sc->sc_lock); return (0); @@ -1731,7 +1741,13 @@ iscsi_ioctl_session_add(struct iscsi_sof return (EBUSY); } - is->is_conn = icl_new_conn(NULL, "iscsi", &is->is_lock); + is->is_conn = icl_new_conn(is->is_conf.isc_offload, + "iscsi", &is->is_lock); + if (is->is_conn == NULL) { + sx_xunlock(&sc->sc_lock); + free(is, M_ISCSI); + return (EINVAL); + } is->is_conn->ic_receive = iscsi_receive_callback; is->is_conn->ic_error = iscsi_error_callback; is->is_conn->ic_prv0 = is; @@ -1836,6 +1852,7 @@ iscsi_ioctl_session_list(struct iscsi_so iss.iss_id = is->is_id; strlcpy(iss.iss_target_alias, is->is_target_alias, sizeof(iss.iss_target_alias)); strlcpy(iss.iss_reason, is->is_reason, sizeof(iss.iss_reason)); + strlcpy(iss.iss_offload, is->is_conn->ic_offload, sizeof(iss.iss_offload)); if (is->is_conn->ic_header_crc32c) iss.iss_header_digest = ISCSI_DIGEST_CRC32C; Modified: head/sys/dev/iscsi/iscsi_ioctl.h ============================================================================== --- head/sys/dev/iscsi/iscsi_ioctl.h Thu Feb 5 03:56:49 2015 (r278231) +++ head/sys/dev/iscsi/iscsi_ioctl.h Thu Feb 5 06:37:59 2015 (r278232) @@ -43,6 +43,7 @@ #define ISCSI_ADDR_LEN 47 /* INET6_ADDRSTRLEN + '\0' */ #define ISCSI_ALIAS_LEN 256 /* XXX: Where did it come from? */ #define ISCSI_SECRET_LEN 17 /* 16 + '\0' */ +#define ISCSI_OFFLOAD_LEN 8 #define ISCSI_REASON_LEN 64 #define ISCSI_DIGEST_NONE 0 @@ -65,7 +66,16 @@ struct iscsi_session_conf { int isc_header_digest; int isc_data_digest; int isc_iser; - int isc_spare[4]; + char isc_offload[ISCSI_OFFLOAD_LEN]; + int isc_spare[2]; +}; + +/* + * Additional constraints imposed by chosen ICL offload module; + * iscsid(8) must obey those when negotiating operational parameters. + */ +struct iscsi_session_limits { + size_t isl_max_data_segment_length; }; /* @@ -81,20 +91,21 @@ struct iscsi_session_state { int iss_immediate_data; int iss_connected; char iss_reason[ISCSI_REASON_LEN]; - int iss_spare[4]; + char iss_offload[ISCSI_OFFLOAD_LEN]; + int iss_spare[2]; }; /* - * For use with iscsid(8). + * The following ioctls are used by iscsid(8). */ - struct iscsi_daemon_request { unsigned int idr_session_id; struct iscsi_session_conf idr_conf; uint8_t idr_isid[6]; uint16_t idr_tsih; uint16_t idr_spare_cid; - int idr_spare[4]; + struct iscsi_session_limits idr_limits; + int idr_spare[2]; }; struct iscsi_daemon_handoff { @@ -182,9 +193,8 @@ struct iscsi_daemon_receive { #endif /* ICL_KERNEL_PROXY */ /* - * For use with iscsictl(8). + * The following ioctls are used by iscsictl(8). */ - struct iscsi_session_add { struct iscsi_session_conf isa_conf; int isa_spare[4]; Modified: head/usr.bin/iscsictl/iscsi.conf.5 ============================================================================== --- head/usr.bin/iscsictl/iscsi.conf.5 Thu Feb 5 03:56:49 2015 (r278231) +++ head/usr.bin/iscsictl/iscsi.conf.5 Thu Feb 5 06:37:59 2015 (r278232) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 17, 2013 +.Dd February 4, 2015 .Dt ISCSI.CONF 5 .Os .Sh NAME @@ -110,6 +110,8 @@ flag of The following are not specified in the .Sy RFC 3720 .Bl -tag -width sockbufsize +.It Cm offload +Name of selected iSCSI hardware offload driver. .It Cm port The iSCSI port used by the iSCSI protocol, defaults to 3260. .It Cm tags Modified: head/usr.bin/iscsictl/iscsictl.c ============================================================================== --- head/usr.bin/iscsictl/iscsictl.c Thu Feb 5 03:56:49 2015 (r278231) +++ head/usr.bin/iscsictl/iscsictl.c Thu Feb 5 06:37:59 2015 (r278232) @@ -327,6 +327,9 @@ conf_from_target(struct iscsi_session_co conf->isc_discovery = 1; if (targ->t_protocol == PROTOCOL_ISER) conf->isc_iser = 1; + if (targ->t_offload != NULL) + strlcpy(conf->isc_offload, targ->t_offload, + sizeof(conf->isc_offload)); if (targ->t_header_digest == DIGEST_CRC32C) conf->isc_header_digest = ISCSI_DIGEST_CRC32C; else @@ -517,6 +520,7 @@ kernel_list(int iscsi_fd, const struct t state->iss_immediate_data ? "Yes" : "No"); printf("iSER (RDMA): %s\n", conf->isc_iser ? "Yes" : "No"); + printf("Offload driver: %s\n", state->iss_offload); printf("Device nodes: "); print_periphs(state->iss_id); printf("\n\n"); Modified: head/usr.bin/iscsictl/iscsictl.h ============================================================================== --- head/usr.bin/iscsictl/iscsictl.h Thu Feb 5 03:56:49 2015 (r278231) +++ head/usr.bin/iscsictl/iscsictl.h Thu Feb 5 06:37:59 2015 (r278232) @@ -72,6 +72,7 @@ struct target { int t_auth_method; int t_session_type; int t_protocol; + char *t_offload; char *t_user; char *t_secret; char *t_mutual_user; Modified: head/usr.bin/iscsictl/parse.y ============================================================================== --- head/usr.bin/iscsictl/parse.y Thu Feb 5 03:56:49 2015 (r278231) +++ head/usr.bin/iscsictl/parse.y Thu Feb 5 06:37:59 2015 (r278232) @@ -57,8 +57,8 @@ extern void yyrestart(FILE *); %token AUTH_METHOD HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS %token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET -%token MUTUAL_USER MUTUAL_SECRET SEMICOLON SESSION_TYPE PROTOCOL IGNORED -%token EQUALS OPENING_BRACKET CLOSING_BRACKET +%token MUTUAL_USER MUTUAL_SECRET SEMICOLON SESSION_TYPE PROTOCOL OFFLOAD +%token IGNORED EQUALS OPENING_BRACKET CLOSING_BRACKET %union { @@ -117,6 +117,8 @@ target_entry: | session_type | + offload + | protocol | ignored @@ -250,6 +252,14 @@ session_type: SESSION_TYPE EQUALS STR } ; +offload: OFFLOAD EQUALS STR + { + if (target->t_offload != NULL) + errx(1, "duplicated offload at line %d", lineno); + target->t_offload = $3; + } + ; + protocol: PROTOCOL EQUALS STR { if (target->t_protocol != PROTOCOL_UNSPECIFIED) Modified: head/usr.bin/iscsictl/token.l ============================================================================== --- head/usr.bin/iscsictl/token.l Thu Feb 5 03:56:49 2015 (r278231) +++ head/usr.bin/iscsictl/token.l Thu Feb 5 06:37:59 2015 (r278232) @@ -63,6 +63,7 @@ tgtChapSecret { return MUTUAL_SECRET; } AuthMethod { return AUTH_METHOD; } SessionType { return SESSION_TYPE; } protocol { return PROTOCOL; } +offload { return OFFLOAD; } port { return IGNORED; } MaxConnections { return IGNORED; } TargetAlias { return IGNORED; } Modified: head/usr.sbin/iscsid/iscsid.c ============================================================================== --- head/usr.sbin/iscsid/iscsid.c Thu Feb 5 03:56:49 2015 (r278231) +++ head/usr.sbin/iscsid/iscsid.c Thu Feb 5 06:37:59 2015 (r278232) @@ -152,7 +152,8 @@ resolve_addr(const struct connection *co static struct connection * connection_new(unsigned int session_id, const uint8_t isid[8], uint16_t tsih, - const struct iscsi_session_conf *conf, int iscsi_fd) + const struct iscsi_session_conf *conf, const struct iscsi_session_limits + *limits, int iscsi_fd) { struct connection *conn; struct addrinfo *from_ai, *to_ai; @@ -186,6 +187,7 @@ connection_new(unsigned int session_id, * XXX: Should we sanitize this somehow? */ memcpy(&conn->conn_conf, conf, sizeof(conn->conn_conf)); + memcpy(&conn->conn_limits, limits, sizeof(conn->conn_limits)); from_addr = conn->conn_conf.isc_initiator_addr; to_addr = conn->conn_conf.isc_target_addr; @@ -443,7 +445,8 @@ handle_request(int iscsi_fd, const struc } conn = connection_new(request->idr_session_id, request->idr_isid, - request->idr_tsih, &request->idr_conf, iscsi_fd); + request->idr_tsih, &request->idr_conf, &request->idr_limits, + iscsi_fd); set_timeout(timeout); capsicate(conn); login(conn); Modified: head/usr.sbin/iscsid/iscsid.h ============================================================================== --- head/usr.sbin/iscsid/iscsid.h Thu Feb 5 03:56:49 2015 (r278231) +++ head/usr.sbin/iscsid/iscsid.h Thu Feb 5 06:37:59 2015 (r278232) @@ -51,6 +51,7 @@ struct connection { int conn_socket; unsigned int conn_session_id; struct iscsi_session_conf conn_conf; + struct iscsi_session_limits conn_limits; char conn_target_alias[ISCSI_ADDR_LEN]; uint8_t conn_isid[6]; uint16_t conn_tsih; Modified: head/usr.sbin/iscsid/login.c ============================================================================== --- head/usr.sbin/iscsid/login.c Thu Feb 5 03:56:49 2015 (r278231) +++ head/usr.sbin/iscsid/login.c Thu Feb 5 06:37:59 2015 (r278232) @@ -441,6 +441,10 @@ login_negotiate(struct connection *conn) request = login_new_request(conn, BHSLR_STAGE_OPERATIONAL_NEGOTIATION); request_keys = keys_new(); + log_debugx("offload \"%s\" limits MaxRecvDataSegmentLength to %zd", + conn->conn_conf.isc_offload, + conn->conn_limits.isl_max_data_segment_length); + /* * The following keys are irrelevant for discovery sessions. */ @@ -456,9 +460,9 @@ login_negotiate(struct connection *conn) keys_add(request_keys, "ImmediateData", "Yes"); keys_add_int(request_keys, "MaxBurstLength", - 2 * ISCSI_MAX_DATA_SEGMENT_LENGTH); + 2 * conn->conn_limits.isl_max_data_segment_length); keys_add_int(request_keys, "FirstBurstLength", - ISCSI_MAX_DATA_SEGMENT_LENGTH); + conn->conn_limits.isl_max_data_segment_length); keys_add(request_keys, "InitialR2T", "Yes"); keys_add(request_keys, "MaxOutstandingR2T", "1"); } else { @@ -467,7 +471,7 @@ login_negotiate(struct connection *conn) } keys_add_int(request_keys, "MaxRecvDataSegmentLength", - ISCSI_MAX_DATA_SEGMENT_LENGTH); + conn->conn_limits.isl_max_data_segment_length); keys_add(request_keys, "DefaultTime2Wait", "0"); keys_add(request_keys, "DefaultTime2Retain", "0"); keys_add(request_keys, "ErrorRecoveryLevel", "0");