aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorEdward Tomasz Napierala <trasz@FreeBSD.org>2016-05-24 08:44:45 +0000
committerEdward Tomasz Napierala <trasz@FreeBSD.org>2016-05-24 08:44:45 +0000
commitb89115941821073fbcfaa1c3e21521b35670f860 (patch)
tree6d697c58c286da70c0d683190cb592a6068bafae /sys
parent9183a497e74a12ab860730b88ef000ed9f343c88 (diff)
downloadsrc-b89115941821073fbcfaa1c3e21521b35670f860.tar.gz
src-b89115941821073fbcfaa1c3e21521b35670f860.zip
Add mechanism for choosing iSER-capable ICL modules.
MFC after: 1 month Sponsored by: The FreeBSD Foundation
Notes
Notes: svn path=/head/; revision=300592
Diffstat (limited to 'sys')
-rw-r--r--sys/cam/ctl/ctl_frontend_iscsi.c5
-rw-r--r--sys/dev/cxgbe/cxgbei/icl_cxgbei.c4
-rw-r--r--sys/dev/iscsi/icl.c55
-rw-r--r--sys/dev/iscsi/icl.h8
-rw-r--r--sys/dev/iscsi/icl_soft.c17
-rw-r--r--sys/dev/iscsi/iscsi.c3
6 files changed, 61 insertions, 31 deletions
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c
index d627eeab4a40..1c270fc2c232 100644
--- a/sys/cam/ctl/ctl_frontend_iscsi.c
+++ b/sys/cam/ctl/ctl_frontend_iscsi.c
@@ -1264,7 +1264,7 @@ cfiscsi_session_new(struct cfiscsi_softc *softc, const char *offload)
cv_init(&cs->cs_login_cv, "cfiscsi_login");
#endif
- cs->cs_conn = icl_new_conn(offload, "cfiscsi", &cs->cs_lock);
+ cs->cs_conn = icl_new_conn(offload, false, "cfiscsi", &cs->cs_lock);
if (cs->cs_conn == NULL) {
free(cs, M_CFISCSI);
return (NULL);
@@ -1793,7 +1793,8 @@ cfiscsi_ioctl_limits(struct ctl_iscsi *ci)
cilp = (struct ctl_iscsi_limits_params *)&(ci->data);
- error = icl_limits(cilp->offload, &cilp->data_segment_limit);
+ error = icl_limits(cilp->offload, false,
+ &cilp->data_segment_limit);
if (error != 0) {
ci->status = CTL_ISCSI_ERROR;
snprintf(ci->error_str, sizeof(ci->error_str),
diff --git a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
index 07a1f229d075..dbb8b75bb47a 100644
--- a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
+++ b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
@@ -850,7 +850,7 @@ icl_cxgbei_load(void)
refcount_init(&icl_cxgbei_ncons, 0);
- error = icl_register("cxgbei", 100, icl_cxgbei_limits,
+ error = icl_register("cxgbei", false, 100, icl_cxgbei_limits,
icl_cxgbei_new_conn);
KASSERT(error == 0, ("failed to register"));
@@ -864,7 +864,7 @@ icl_cxgbei_unload(void)
if (icl_cxgbei_ncons != 0)
return (EBUSY);
- icl_unregister("cxgbei");
+ icl_unregister("cxgbei", false);
uma_zdestroy(icl_transfer_zone);
diff --git a/sys/dev/iscsi/icl.c b/sys/dev/iscsi/icl.c
index 921fc2a1568b..ffb776423e17 100644
--- a/sys/dev/iscsi/icl.c
+++ b/sys/dev/iscsi/icl.c
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
struct icl_module {
TAILQ_ENTRY(icl_module) im_next;
char *im_name;
+ bool im_iser;
int im_priority;
int (*im_limits)(size_t *limitp);
struct icl_conn *(*im_new_conn)(const char *name,
@@ -106,7 +107,7 @@ sysctl_kern_icl_drivers(SYSCTL_HANDLER_ARGS)
}
static struct icl_module *
-icl_find(const char *name)
+icl_find(const char *name, bool iser, bool quiet)
{
struct icl_module *im, *im_max;
@@ -117,34 +118,52 @@ icl_find(const char *name)
* priority.
*/
if (name == NULL || name[0] == '\0') {
- im_max = TAILQ_FIRST(&sc->sc_modules);
+ im_max = NULL;
TAILQ_FOREACH(im, &sc->sc_modules, im_next) {
- if (im->im_priority > im_max->im_priority)
+ if (im->im_iser != iser)
+ continue;
+ if (im_max == NULL ||
+ im->im_priority > im_max->im_priority)
im_max = im;
}
+ if (iser && im_max == NULL && !quiet)
+ ICL_WARN("no iSER-capable offload found");
+
return (im_max);
}
TAILQ_FOREACH(im, &sc->sc_modules, im_next) {
- if (strcasecmp(im->im_name, name) == 0)
- return (im);
+ if (strcasecmp(im->im_name, name) != 0)
+ continue;
+
+ if (!im->im_iser && iser && !quiet) {
+ ICL_WARN("offload \"%s\" is not iSER-capable", name);
+ return (NULL);
+ }
+ if (im->im_iser && !iser && !quiet) {
+ ICL_WARN("offload \"%s\" is iSER-only", name);
+ return (NULL);
+ }
+
+ return (im);
}
+ if (!quiet)
+ ICL_WARN("offload \"%s\" not found", name);
+
return (NULL);
}
struct icl_conn *
-icl_new_conn(const char *offload, const char *name, struct mtx *lock)
+icl_new_conn(const char *offload, bool iser, const char *name, struct mtx *lock)
{
struct icl_module *im;
struct icl_conn *ic;
sx_slock(&sc->sc_lock);
- im = icl_find(offload);
-
+ im = icl_find(offload, iser, false);
if (im == NULL) {
- ICL_WARN("offload \"%s\" not found", offload);
sx_sunlock(&sc->sc_lock);
return (NULL);
}
@@ -156,16 +175,14 @@ icl_new_conn(const char *offload, const char *name, struct mtx *lock)
}
int
-icl_limits(const char *offload, size_t *limitp)
+icl_limits(const char *offload, bool iser, size_t *limitp)
{
struct icl_module *im;
int error;
sx_slock(&sc->sc_lock);
- im = icl_find(offload);
-
+ im = icl_find(offload, iser, false);
if (im == NULL) {
- ICL_WARN("offload \"%s\" not found", offload);
sx_sunlock(&sc->sc_lock);
return (ENXIO);
}
@@ -176,16 +193,14 @@ icl_limits(const char *offload, size_t *limitp)
return (error);
}
-
int
-icl_register(const char *offload, int priority, int (*limits)(size_t *),
+icl_register(const char *offload, bool iser, int priority, int (*limits)(size_t *),
struct icl_conn *(*new_conn)(const char *, struct mtx *))
{
struct icl_module *im;
sx_xlock(&sc->sc_lock);
- im = icl_find(offload);
-
+ im = icl_find(offload, iser, true);
if (im != NULL) {
ICL_WARN("offload \"%s\" already registered", offload);
sx_xunlock(&sc->sc_lock);
@@ -194,6 +209,7 @@ icl_register(const char *offload, int priority, int (*limits)(size_t *),
im = malloc(sizeof(*im), M_ICL, M_ZERO | M_WAITOK);
im->im_name = strdup(offload, M_ICL);
+ im->im_iser = iser;
im->im_priority = priority;
im->im_limits = limits;
im->im_new_conn = new_conn;
@@ -206,13 +222,12 @@ icl_register(const char *offload, int priority, int (*limits)(size_t *),
}
int
-icl_unregister(const char *offload)
+icl_unregister(const char *offload, bool rdma)
{
struct icl_module *im;
sx_xlock(&sc->sc_lock);
- im = icl_find(offload);
-
+ im = icl_find(offload, rdma, true);
if (im == NULL) {
ICL_WARN("offload \"%s\" not registered", offload);
sx_xunlock(&sc->sc_lock);
diff --git a/sys/dev/iscsi/icl.h b/sys/dev/iscsi/icl.h
index 29d115301dee..292fa6006657 100644
--- a/sys/dev/iscsi/icl.h
+++ b/sys/dev/iscsi/icl.h
@@ -126,14 +126,14 @@ struct icl_conn {
void *ic_prv0;
};
-struct icl_conn *icl_new_conn(const char *offload, const char *name,
+struct icl_conn *icl_new_conn(const char *offload, bool iser, const char *name,
struct mtx *lock);
-int icl_limits(const char *offload, size_t *limitp);
+int icl_limits(const char *offload, bool iser, size_t *limitp);
-int icl_register(const char *offload, int priority,
+int icl_register(const char *offload, bool iser, int priority,
int (*limits)(size_t *),
struct icl_conn *(*new_conn)(const char *, struct mtx *));
-int icl_unregister(const char *offload);
+int icl_unregister(const char *offload, bool rdma);
#ifdef ICL_KERNEL_PROXY
diff --git a/sys/dev/iscsi/icl_soft.c b/sys/dev/iscsi/icl_soft.c
index c38493f05abc..4efae9fd9712 100644
--- a/sys/dev/iscsi/icl_soft.c
+++ b/sys/dev/iscsi/icl_soft.c
@@ -1531,9 +1531,19 @@ icl_soft_load(void)
* it's known as "offload driver"; "offload driver: soft"
* doesn't make much sense.
*/
- error = icl_register("none", 0, icl_soft_limits, icl_soft_new_conn);
+ error = icl_register("none", false, 0,
+ icl_soft_limits, icl_soft_new_conn);
KASSERT(error == 0, ("failed to register"));
+#if defined(ICL_KERNEL_PROXY) && 0
+ /*
+ * Debugging aid for kernel proxy functionality.
+ */
+ error = icl_register("proxytest", true, 0,
+ icl_soft_limits, icl_soft_new_conn);
+ KASSERT(error == 0, ("failed to register"));
+#endif
+
return (error);
}
@@ -1544,7 +1554,10 @@ icl_soft_unload(void)
if (icl_ncons != 0)
return (EBUSY);
- icl_unregister("none");
+ icl_unregister("none", false);
+#if defined(ICL_KERNEL_PROXY) && 0
+ icl_unregister("proxytest", true);
+#endif
uma_zdestroy(icl_pdu_zone);
diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c
index 86e3fe45091a..a4576cad746e 100644
--- a/sys/dev/iscsi/iscsi.c
+++ b/sys/dev/iscsi/iscsi.c
@@ -1324,6 +1324,7 @@ iscsi_ioctl_daemon_wait(struct iscsi_softc *sc,
sizeof(request->idr_conf));
error = icl_limits(is->is_conf.isc_offload,
+ is->is_conf.isc_iser,
&request->idr_limits.isl_max_data_segment_length);
if (error != 0) {
ISCSI_SESSION_WARN(is, "icl_limits for offload \"%s\" "
@@ -1773,7 +1774,7 @@ iscsi_ioctl_session_add(struct iscsi_softc *sc, struct iscsi_session_add *isa)
}
is->is_conn = icl_new_conn(is->is_conf.isc_offload,
- "iscsi", &is->is_lock);
+ is->is_conf.isc_iser, "iscsi", &is->is_lock);
if (is->is_conn == NULL) {
sx_xunlock(&sc->sc_lock);
free(is, M_ISCSI);