Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F97564985
D34928.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D34928.diff
View Options
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c
--- a/sys/cam/ctl/ctl_frontend_iscsi.c
+++ b/sys/cam/ctl/ctl_frontend_iscsi.c
@@ -1896,7 +1896,7 @@
cilp = (struct ctl_iscsi_limits_params *)&(ci->data);
- error = icl_limits(cilp->offload, false, &idl);
+ error = icl_limits(cilp->offload, false, cilp->socket, &idl);
if (error != 0) {
ci->status = CTL_ISCSI_ERROR;
snprintf(ci->error_str, sizeof(ci->error_str),
diff --git a/sys/cam/ctl/ctl_ioctl.h b/sys/cam/ctl/ctl_ioctl.h
--- a/sys/cam/ctl/ctl_ioctl.h
+++ b/sys/cam/ctl/ctl_ioctl.h
@@ -669,9 +669,12 @@
struct ctl_iscsi_limits_params {
/* passed to kernel */
char offload[CTL_ISCSI_OFFLOAD_LEN];
+ int socket;
/* passed to userland */
- size_t spare;
+#ifdef __LP64__
+ int spare;
+#endif
int max_recv_data_segment_length;
int max_send_data_segment_length;
int max_burst_length;
diff --git a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
--- a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
+++ b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
@@ -1773,7 +1773,7 @@
}
static int
-icl_cxgbei_limits(struct icl_drv_limits *idl)
+icl_cxgbei_limits(struct icl_drv_limits *idl, int socket)
{
/* Maximum allowed by the RFC. cxgbei_limits will clip them. */
diff --git a/sys/dev/iscsi/icl.h b/sys/dev/iscsi/icl.h
--- a/sys/dev/iscsi/icl.h
+++ b/sys/dev/iscsi/icl.h
@@ -137,10 +137,10 @@
struct icl_conn *icl_new_conn(const char *offload, bool iser, const char *name,
struct mtx *lock);
-int icl_limits(const char *offload, bool iser,
+int icl_limits(const char *offload, bool iser, int socket,
struct icl_drv_limits *idl);
int icl_register(const char *offload, bool iser, int priority,
- int (*limits)(struct icl_drv_limits *),
+ int (*limits)(struct icl_drv_limits *, int),
struct icl_conn *(*new_conn)(const char *, struct mtx *));
int icl_unregister(const char *offload, bool rdma);
diff --git a/sys/dev/iscsi/icl.c b/sys/dev/iscsi/icl.c
--- a/sys/dev/iscsi/icl.c
+++ b/sys/dev/iscsi/icl.c
@@ -60,7 +60,8 @@
char *im_name;
bool im_iser;
int im_priority;
- int (*im_limits)(struct icl_drv_limits *idl);
+ int (*im_limits)(struct icl_drv_limits *idl,
+ int socket);
struct icl_conn *(*im_new_conn)(const char *name,
struct mtx *lock);
};
@@ -184,7 +185,8 @@
}
int
-icl_limits(const char *offload, bool iser, struct icl_drv_limits *idl)
+icl_limits(const char *offload, bool iser, int socket,
+ struct icl_drv_limits *idl)
{
struct icl_module *im;
int error;
@@ -197,7 +199,7 @@
return (ENXIO);
}
- error = im->im_limits(idl);
+ error = im->im_limits(idl, socket);
sx_sunlock(&sc->sc_lock);
/*
@@ -232,7 +234,7 @@
int
icl_register(const char *offload, bool iser, int priority,
- int (*limits)(struct icl_drv_limits *),
+ int (*limits)(struct icl_drv_limits *, int),
struct icl_conn *(*new_conn)(const char *, struct mtx *))
{
struct icl_module *im;
diff --git a/sys/dev/iscsi/icl_soft.c b/sys/dev/iscsi/icl_soft.c
--- a/sys/dev/iscsi/icl_soft.c
+++ b/sys/dev/iscsi/icl_soft.c
@@ -1652,7 +1652,7 @@
}
static int
-icl_soft_limits(struct icl_drv_limits *idl)
+icl_soft_limits(struct icl_drv_limits *idl, int socket)
{
idl->idl_max_recv_data_segment_length = max_data_segment_length;
diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c
--- a/sys/dev/iscsi/iscsi.c
+++ b/sys/dev/iscsi/iscsi.c
@@ -78,6 +78,20 @@
FEATURE(iscsi_kernel_proxy, "iSCSI initiator built with ICL_KERNEL_PROXY");
#endif
+#ifdef COMPAT_FREEBSD13
+struct iscsi_daemon_request13 {
+ 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;
+ struct iscsi_session_limits idr_limits;
+ int idr_spare[4];
+};
+
+#define ISCSIDWAIT13 _IOR('I', 0x01, struct iscsi_daemon_request13)
+#endif
+
/*
* XXX: This is global so the iscsi_unload() can access it.
* Think about how to do this properly.
@@ -1423,10 +1437,9 @@
static int
iscsi_ioctl_daemon_wait(struct iscsi_softc *sc,
- struct iscsi_daemon_request *request)
+ struct iscsi_daemon_request *request, bool freebsd13)
{
struct iscsi_session *is;
- struct icl_drv_limits idl;
int error;
sx_slock(&sc->sc_lock);
@@ -1472,29 +1485,78 @@
memcpy(&request->idr_conf, &is->is_conf,
sizeof(request->idr_conf));
- error = icl_limits(is->is_conf.isc_offload,
- is->is_conf.isc_iser, &idl);
- 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);
- }
- request->idr_limits.isl_max_recv_data_segment_length =
- idl.idl_max_recv_data_segment_length;
- request->idr_limits.isl_max_send_data_segment_length =
- idl.idl_max_send_data_segment_length;
- request->idr_limits.isl_max_burst_length =
- idl.idl_max_burst_length;
- request->idr_limits.isl_first_burst_length =
- idl.idl_first_burst_length;
+#ifdef COMPAT_FREEBSD13
+ if (freebsd13) {
+ struct icl_drv_limits idl;
+ struct iscsi_daemon_request13 *request13;
+ error = icl_limits(is->is_conf.isc_offload,
+ is->is_conf.isc_iser, 0, &idl);
+ 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);
+ }
+ request13 = (struct iscsi_daemon_request13 *)request;
+ request13->idr_limits.isl_max_recv_data_segment_length =
+ idl.idl_max_recv_data_segment_length;
+ request13->idr_limits.isl_max_send_data_segment_length =
+ idl.idl_max_send_data_segment_length;
+ request13->idr_limits.isl_max_burst_length =
+ idl.idl_max_burst_length;
+ request13->idr_limits.isl_first_burst_length =
+ idl.idl_first_burst_length;
+ }
+#endif
sx_sunlock(&sc->sc_lock);
return (0);
}
}
+static int
+iscsi_ioctl_daemon_limits(struct iscsi_softc *sc,
+ struct iscsi_daemon_limits *limits)
+{
+ struct icl_drv_limits idl;
+ struct iscsi_session *is;
+ int error;
+
+ sx_slock(&sc->sc_lock);
+
+ /*
+ * Find the session to fetch limits for.
+ */
+ TAILQ_FOREACH(is, &sc->sc_sessions, is_next) {
+ if (is->is_id == limits->idl_session_id)
+ break;
+ }
+ if (is == NULL) {
+ sx_sunlock(&sc->sc_lock);
+ return (ESRCH);
+ }
+
+ error = icl_limits(is->is_conf.isc_offload, is->is_conf.isc_iser,
+ limits->idl_socket, &idl);
+ sx_sunlock(&sc->sc_lock);
+ if (error != 0) {
+ ISCSI_SESSION_WARN(is, "icl_limits for offload \"%s\" "
+ "failed with error %d", is->is_conf.isc_offload, error);
+ return (error);
+ }
+ limits->idl_limits.isl_max_recv_data_segment_length =
+ idl.idl_max_recv_data_segment_length;
+ limits->idl_limits.isl_max_send_data_segment_length =
+ idl.idl_max_send_data_segment_length;
+ limits->idl_limits.isl_max_burst_length =
+ idl.idl_max_burst_length;
+ limits->idl_limits.isl_first_burst_length =
+ idl.idl_first_burst_length;
+
+ return (0);
+}
+
static int
iscsi_ioctl_daemon_handoff(struct iscsi_softc *sc,
struct iscsi_daemon_handoff *handoff)
@@ -2179,7 +2241,15 @@
switch (cmd) {
case ISCSIDWAIT:
return (iscsi_ioctl_daemon_wait(sc,
- (struct iscsi_daemon_request *)arg));
+ (struct iscsi_daemon_request *)arg, false));
+#ifdef COMPAT_FREEBSD13
+ case ISCSIDWAIT13:
+ return (iscsi_ioctl_daemon_wait(sc,
+ (struct iscsi_daemon_request *)arg, true));
+#endif
+ case ISCSIDLIMITS:
+ return (iscsi_ioctl_daemon_limits(sc,
+ (struct iscsi_daemon_limits *)arg));
case ISCSIDHANDOFF:
return (iscsi_ioctl_daemon_handoff(sc,
(struct iscsi_daemon_handoff *)arg));
diff --git a/sys/dev/iscsi/iscsi_ioctl.h b/sys/dev/iscsi/iscsi_ioctl.h
--- a/sys/dev/iscsi/iscsi_ioctl.h
+++ b/sys/dev/iscsi/iscsi_ioctl.h
@@ -117,10 +117,15 @@
uint8_t idr_isid[6];
uint16_t idr_tsih;
uint16_t idr_spare_cid;
- struct iscsi_session_limits idr_limits;
int idr_spare[4];
};
+struct iscsi_daemon_limits {
+ unsigned int idl_session_id;
+ int idl_socket;
+ struct iscsi_session_limits idl_limits;
+};
+
struct iscsi_daemon_handoff {
unsigned int idh_session_id;
int idh_socket;
@@ -150,6 +155,7 @@
#define ISCSIDWAIT _IOR('I', 0x01, struct iscsi_daemon_request)
#define ISCSIDHANDOFF _IOW('I', 0x02, struct iscsi_daemon_handoff)
#define ISCSIDFAIL _IOW('I', 0x03, struct iscsi_daemon_fail)
+#define ISCSIDLIMITS _IOWR('I', 0x07, struct iscsi_daemon_limits)
#ifdef ICL_KERNEL_PROXY
diff --git a/sys/dev/iser/icl_iser.c b/sys/dev/iser/icl_iser.c
--- a/sys/dev/iser/icl_iser.c
+++ b/sys/dev/iser/icl_iser.c
@@ -511,7 +511,7 @@
}
static int
-iser_limits(struct icl_drv_limits *idl)
+iser_limits(struct icl_drv_limits *idl, int socket)
{
idl->idl_max_recv_data_segment_length = 128 * 1024;
diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h
--- a/usr.sbin/ctld/ctld.h
+++ b/usr.sbin/ctld/ctld.h
@@ -356,7 +356,7 @@
int kernel_lun_modify(struct lun *lun);
int kernel_lun_remove(struct lun *lun);
void kernel_handoff(struct ctld_connection *conn);
-void kernel_limits(const char *offload,
+void kernel_limits(const char *offload, int s,
int *max_recv_data_segment_length,
int *max_send_data_segment_length,
int *max_burst_length,
diff --git a/usr.sbin/ctld/kernel.c b/usr.sbin/ctld/kernel.c
--- a/usr.sbin/ctld/kernel.c
+++ b/usr.sbin/ctld/kernel.c
@@ -954,7 +954,7 @@
}
void
-kernel_limits(const char *offload, int *max_recv_dsl, int *max_send_dsl,
+kernel_limits(const char *offload, int s, int *max_recv_dsl, int *max_send_dsl,
int *max_burst_length, int *first_burst_length)
{
struct ctl_iscsi req;
@@ -967,6 +967,7 @@
if (offload != NULL) {
strlcpy(cilp->offload, offload, sizeof(cilp->offload));
}
+ cilp->socket = s;
if (ioctl(ctl_fd, CTL_ISCSI, &req) == -1) {
log_err(1, "error issuing CTL_ISCSI ioctl; "
diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c
--- a/usr.sbin/ctld/login.c
+++ b/usr.sbin/ctld/login.c
@@ -698,6 +698,7 @@
conn->conn_max_burst_limit = (1 << 24) - 1;
conn->conn_first_burst_limit = (1 << 24) - 1;
kernel_limits(conn->conn_portal->p_portal_group->pg_offload,
+ conn->conn.conn_socket,
&conn->conn_max_recv_data_segment_limit,
&conn->conn_max_send_data_segment_limit,
&conn->conn_max_burst_limit,
diff --git a/usr.sbin/iscsid/iscsid.c b/usr.sbin/iscsid/iscsid.c
--- a/usr.sbin/iscsid/iscsid.c
+++ b/usr.sbin/iscsid/iscsid.c
@@ -225,7 +225,6 @@
connection_new(int iscsi_fd, const struct iscsi_daemon_request *request)
{
struct iscsid_connection *conn;
- struct iscsi_session_limits *isl;
struct addrinfo *from_ai, *to_ai;
const char *from_addr, *to_addr;
#ifdef ICL_KERNEL_PROXY
@@ -249,38 +248,6 @@
sizeof(conn->conn.conn_isid));
conn->conn.conn_tsih = request->idr_tsih;
- /*
- * Read the driver limits and provide reasonable defaults for the ones
- * the driver doesn't care about. If a max_snd_dsl is not explicitly
- * provided by the driver then we'll make sure both conn->max_snd_dsl
- * and isl->max_snd_dsl are set to the rcv_dsl. This preserves historic
- * behavior.
- */
- isl = &conn->conn_limits;
- memcpy(isl, &request->idr_limits, sizeof(*isl));
- if (isl->isl_max_recv_data_segment_length == 0)
- isl->isl_max_recv_data_segment_length = (1 << 24) - 1;
- if (isl->isl_max_send_data_segment_length == 0)
- isl->isl_max_send_data_segment_length =
- isl->isl_max_recv_data_segment_length;
- if (isl->isl_max_burst_length == 0)
- isl->isl_max_burst_length = (1 << 24) - 1;
- if (isl->isl_first_burst_length == 0)
- isl->isl_first_burst_length = (1 << 24) - 1;
- if (isl->isl_first_burst_length > isl->isl_max_burst_length)
- isl->isl_first_burst_length = isl->isl_max_burst_length;
-
- /*
- * Limit default send length in case it won't be negotiated.
- * We can't do it for other limits, since they may affect both
- * sender and receiver operation, and we must obey defaults.
- */
- if (conn->conn.conn_max_send_data_segment_length >
- isl->isl_max_send_data_segment_length) {
- conn->conn.conn_max_send_data_segment_length =
- isl->isl_max_send_data_segment_length;
- }
-
from_addr = conn->conn_conf.isc_initiator_addr;
to_addr = conn->conn_conf.isc_target_addr;
@@ -436,6 +403,56 @@
return (conn);
}
+static void
+limits(struct iscsid_connection *conn)
+{
+ struct iscsi_daemon_limits idl;
+ struct iscsi_session_limits *isl;
+ int error;
+
+ log_debugx("fetching limits from the kernel");
+
+ memset(&idl, 0, sizeof(idl));
+ idl.idl_session_id = conn->conn_session_id;
+ idl.idl_socket = conn->conn.conn_socket;
+
+ error = ioctl(conn->conn_iscsi_fd, ISCSIDLIMITS, &idl);
+ if (error != 0)
+ log_err(1, "ISCSIDLIMITS");
+
+ /*
+ * Read the driver limits and provide reasonable defaults for the ones
+ * the driver doesn't care about. If a max_snd_dsl is not explicitly
+ * provided by the driver then we'll make sure both conn->max_snd_dsl
+ * and isl->max_snd_dsl are set to the rcv_dsl. This preserves historic
+ * behavior.
+ */
+ isl = &conn->conn_limits;
+ memcpy(isl, &idl.idl_limits, sizeof(*isl));
+ if (isl->isl_max_recv_data_segment_length == 0)
+ isl->isl_max_recv_data_segment_length = (1 << 24) - 1;
+ if (isl->isl_max_send_data_segment_length == 0)
+ isl->isl_max_send_data_segment_length =
+ isl->isl_max_recv_data_segment_length;
+ if (isl->isl_max_burst_length == 0)
+ isl->isl_max_burst_length = (1 << 24) - 1;
+ if (isl->isl_first_burst_length == 0)
+ isl->isl_first_burst_length = (1 << 24) - 1;
+ if (isl->isl_first_burst_length > isl->isl_max_burst_length)
+ isl->isl_first_burst_length = isl->isl_max_burst_length;
+
+ /*
+ * Limit default send length in case it won't be negotiated.
+ * We can't do it for other limits, since they may affect both
+ * sender and receiver operation, and we must obey defaults.
+ */
+ if (conn->conn.conn_max_send_data_segment_length >
+ isl->isl_max_send_data_segment_length) {
+ conn->conn.conn_max_send_data_segment_length =
+ isl->isl_max_send_data_segment_length;
+ }
+}
+
static void
handoff(struct iscsid_connection *conn)
{
@@ -502,6 +519,7 @@
ISCSIDSEND,
ISCSIDRECEIVE,
#endif
+ ISCSIDLIMITS,
ISCSIDHANDOFF,
ISCSIDFAIL,
ISCSISADD,
@@ -626,8 +644,9 @@
}
conn = connection_new(iscsi_fd, request);
- set_timeout(timeout);
capsicate(conn);
+ limits(conn);
+ set_timeout(timeout);
login(conn);
if (conn->conn_conf.isc_discovery != 0)
discovery(conn);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Oct 1, 2:32 AM (22 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13222594
Default Alt Text
D34928.diff (14 KB)
Attached To
Mode
D34928: iscsi: Fetch limits based on a socket rather than assuming global limits.
Attached
Detach File
Event Timeline
Log In to Comment