Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 21 Jan 2017 08:33:45 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r312576 - stable/11/sys/cam/ctl
Message-ID:  <201701210833.v0L8XjFN020815@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sat Jan 21 08:33:44 2017
New Revision: 312576
URL: https://svnweb.freebsd.org/changeset/base/312576

Log:
  MFC r310635: Decouple limits on number of LUNs per port and LUs per CTL.
  
  Those two values are not directly related, so make them independent.
  This does not change any limits immediately, but makes number of LUNs
  per port controllable via tunable/sysctl kern.cam.ctl.lun_map_size.
  After this change increasing CTL_MAX_LUNS should be pretty cheap,
  and even making it tunable should be easy.

Modified:
  stable/11/sys/cam/ctl/ctl.c
  stable/11/sys/cam/ctl/ctl_frontend.c
  stable/11/sys/cam/ctl/ctl_frontend.h
  stable/11/sys/cam/ctl/ctl_io.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/cam/ctl/ctl.c
==============================================================================
--- stable/11/sys/cam/ctl/ctl.c	Sat Jan 21 08:32:56 2017	(r312575)
+++ stable/11/sys/cam/ctl/ctl.c	Sat Jan 21 08:33:44 2017	(r312576)
@@ -407,6 +407,9 @@ SYSCTL_INT(_kern_cam_ctl, OID_AUTO, work
 static int ctl_debug = CTL_DEBUG_NONE;
 SYSCTL_INT(_kern_cam_ctl, OID_AUTO, debug, CTLFLAG_RWTUN,
     &ctl_debug, 0, "Enabled debug flags");
+static int ctl_lun_map_size = 1024;
+SYSCTL_INT(_kern_cam_ctl, OID_AUTO, lun_map_size, CTLFLAG_RWTUN,
+    &ctl_lun_map_size, 0, "Size of per-port LUN map (max LUN + 1)");
 
 /*
  * Supported pages (0x00), Serial number (0x80), Device ID (0x83),
@@ -826,7 +829,7 @@ ctl_isc_announce_port(struct ctl_port *p
 		return;
 	i = sizeof(msg->port) + strlen(port->port_name) + 1;
 	if (port->lun_map)
-		i += sizeof(uint32_t) * CTL_MAX_LUNS;
+		i += port->lun_map_size * sizeof(uint32_t);
 	if (port->port_devid)
 		i += port->port_devid->len;
 	if (port->target_devid)
@@ -846,7 +849,7 @@ ctl_isc_announce_port(struct ctl_port *p
 	    "%d:%s", softc->ha_id, port->port_name) + 1;
 	i += msg->port.name_len;
 	if (port->lun_map) {
-		msg->port.lun_map_len = sizeof(uint32_t) * CTL_MAX_LUNS;
+		msg->port.lun_map_len = port->lun_map_size * sizeof(uint32_t);
 		memcpy(&msg->port.data[i], port->lun_map,
 		    msg->port.lun_map_len);
 		i += msg->port.lun_map_len;
@@ -1155,19 +1158,25 @@ ctl_isc_port_sync(struct ctl_softc *soft
 	    M_CTL);
 	i += msg->port.name_len;
 	if (msg->port.lun_map_len != 0) {
-		if (port->lun_map == NULL)
-			port->lun_map = malloc(sizeof(uint32_t) * CTL_MAX_LUNS,
+		if (port->lun_map == NULL ||
+		    port->lun_map_size * sizeof(uint32_t) <
+		    msg->port.lun_map_len) {
+			port->lun_map_size = 0;
+			free(port->lun_map, M_CTL);
+			port->lun_map = malloc(msg->port.lun_map_len,
 			    M_CTL, M_WAITOK);
-		memcpy(port->lun_map, &msg->port.data[i],
-		    sizeof(uint32_t) * CTL_MAX_LUNS);
+		}
+		memcpy(port->lun_map, &msg->port.data[i], msg->port.lun_map_len);
+		port->lun_map_size = msg->port.lun_map_len / sizeof(uint32_t);
 		i += msg->port.lun_map_len;
 	} else {
+		port->lun_map_size = 0;
 		free(port->lun_map, M_CTL);
 		port->lun_map = NULL;
 	}
 	if (msg->port.port_devid_len != 0) {
 		if (port->port_devid == NULL ||
-		    port->port_devid->len != msg->port.port_devid_len) {
+		    port->port_devid->len < msg->port.port_devid_len) {
 			free(port->port_devid, M_CTL);
 			port->port_devid = malloc(sizeof(struct ctl_devid) +
 			    msg->port.port_devid_len, M_CTL, M_WAITOK);
@@ -1182,7 +1191,7 @@ ctl_isc_port_sync(struct ctl_softc *soft
 	}
 	if (msg->port.target_devid_len != 0) {
 		if (port->target_devid == NULL ||
-		    port->target_devid->len != msg->port.target_devid_len) {
+		    port->target_devid->len < msg->port.target_devid_len) {
 			free(port->target_devid, M_CTL);
 			port->target_devid = malloc(sizeof(struct ctl_devid) +
 			    msg->port.target_devid_len, M_CTL, M_WAITOK);
@@ -1197,7 +1206,7 @@ ctl_isc_port_sync(struct ctl_softc *soft
 	}
 	if (msg->port.init_devid_len != 0) {
 		if (port->init_devid == NULL ||
-		    port->init_devid->len != msg->port.init_devid_len) {
+		    port->init_devid->len < msg->port.init_devid_len) {
 			free(port->init_devid, M_CTL);
 			port->init_devid = malloc(sizeof(struct ctl_devid) +
 			    msg->port.init_devid_len, M_CTL, M_WAITOK);
@@ -3295,7 +3304,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, 
 
 			if (port->lun_map != NULL) {
 				sbuf_printf(sb, "\t<lun_map>on</lun_map>\n");
-				for (j = 0; j < CTL_MAX_LUNS; j++) {
+				for (j = 0; j < port->lun_map_size; j++) {
 					plun = ctl_lun_map_from_port(port, j);
 					if (plun == UINT32_MAX)
 						continue;
@@ -3375,7 +3384,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, 
 			}
 		}
 		mtx_unlock(&softc->ctl_lock); // XXX: port_enable sleeps
-		if (lm->plun < CTL_MAX_LUNS) {
+		if (lm->plun != UINT32_MAX) {
 			if (lm->lun == UINT32_MAX)
 				retval = ctl_lun_map_unset(port, lm->plun);
 			else if (lm->lun < CTL_MAX_LUNS &&
@@ -3383,13 +3392,12 @@ ctl_ioctl(struct cdev *dev, u_long cmd, 
 				retval = ctl_lun_map_set(port, lm->plun, lm->lun);
 			else
 				return (ENXIO);
-		} else if (lm->plun == UINT32_MAX) {
+		} else {
 			if (lm->lun == UINT32_MAX)
 				retval = ctl_lun_map_deinit(port);
 			else
 				retval = ctl_lun_map_init(port);
-		} else
-			return (ENXIO);
+		}
 		if (port->status & CTL_PORT_STATUS_ONLINE)
 			ctl_isc_announce_port(port);
 		break;
@@ -3442,15 +3450,20 @@ ctl_lun_map_init(struct ctl_port *port)
 {
 	struct ctl_softc *softc = port->ctl_softc;
 	struct ctl_lun *lun;
+	int size = ctl_lun_map_size;
 	uint32_t i;
 
-	if (port->lun_map == NULL)
-		port->lun_map = malloc(sizeof(uint32_t) * CTL_MAX_LUNS,
+	if (port->lun_map == NULL || port->lun_map_size < size) {
+		port->lun_map_size = 0;
+		free(port->lun_map, M_CTL);
+		port->lun_map = malloc(size * sizeof(uint32_t),
 		    M_CTL, M_NOWAIT);
+	}
 	if (port->lun_map == NULL)
 		return (ENOMEM);
-	for (i = 0; i < CTL_MAX_LUNS; i++)
+	for (i = 0; i < size; i++)
 		port->lun_map[i] = UINT32_MAX;
+	port->lun_map_size = size;
 	if (port->status & CTL_PORT_STATUS_ONLINE) {
 		if (port->lun_disable != NULL) {
 			STAILQ_FOREACH(lun, &softc->lun_list, links)
@@ -3469,6 +3482,7 @@ ctl_lun_map_deinit(struct ctl_port *port
 
 	if (port->lun_map == NULL)
 		return (0);
+	port->lun_map_size = 0;
 	free(port->lun_map, M_CTL);
 	port->lun_map = NULL;
 	if (port->status & CTL_PORT_STATUS_ONLINE) {
@@ -3492,6 +3506,8 @@ ctl_lun_map_set(struct ctl_port *port, u
 		if (status != 0)
 			return (status);
 	}
+	if (plun >= port->lun_map_size)
+		return (EINVAL);
 	old = port->lun_map[plun];
 	port->lun_map[plun] = glun;
 	if ((port->status & CTL_PORT_STATUS_ONLINE) && old == UINT32_MAX) {
@@ -3507,7 +3523,7 @@ ctl_lun_map_unset(struct ctl_port *port,
 {
 	uint32_t old;
 
-	if (port->lun_map == NULL)
+	if (port->lun_map == NULL || plun >= port->lun_map_size)
 		return (0);
 	old = port->lun_map[plun];
 	port->lun_map[plun] = UINT32_MAX;
@@ -3525,8 +3541,10 @@ ctl_lun_map_from_port(struct ctl_port *p
 
 	if (port == NULL)
 		return (UINT32_MAX);
-	if (port->lun_map == NULL || lun_id == UINT32_MAX)
+	if (port->lun_map == NULL)
 		return (lun_id);
+	if (lun_id > port->lun_map_size)
+		return (UINT32_MAX);
 	return (port->lun_map[lun_id]);
 }
 
@@ -3539,7 +3557,7 @@ ctl_lun_map_to_port(struct ctl_port *por
 		return (UINT32_MAX);
 	if (port->lun_map == NULL)
 		return (lun_id);
-	for (i = 0; i < CTL_MAX_LUNS; i++) {
+	for (i = 0; i < port->lun_map_size; i++) {
 		if (port->lun_map[i] == lun_id)
 			return (i);
 	}
@@ -9048,9 +9066,8 @@ ctl_report_luns(struct ctl_scsiio *ctsio
 	struct scsi_report_luns_data *lun_data;
 	struct ctl_lun *lun, *request_lun;
 	struct ctl_port *port;
-	int num_luns, retval;
+	int num_filled, num_luns, num_port_luns, retval;
 	uint32_t alloc_len, lun_datalen;
-	int num_filled;
 	uint32_t initidx, targ_lun_id, lun_id;
 
 	retval = CTL_RETVAL_COMPLETE;
@@ -9060,9 +9077,10 @@ ctl_report_luns(struct ctl_scsiio *ctsio
 
 	CTL_DEBUG_PRINT(("ctl_report_luns\n"));
 
-	mtx_lock(&softc->ctl_lock);
 	num_luns = 0;
-	for (targ_lun_id = 0; targ_lun_id < CTL_MAX_LUNS; targ_lun_id++) {
+	num_port_luns = port->lun_map ? port->lun_map_size : CTL_MAX_LUNS;
+	mtx_lock(&softc->ctl_lock);
+	for (targ_lun_id = 0; targ_lun_id < num_port_luns; targ_lun_id++) {
 		if (ctl_lun_map_from_port(port, targ_lun_id) != UINT32_MAX)
 			num_luns++;
 	}
@@ -9121,7 +9139,9 @@ ctl_report_luns(struct ctl_scsiio *ctsio
 	initidx = ctl_get_initindex(&ctsio->io_hdr.nexus);
 
 	mtx_lock(&softc->ctl_lock);
-	for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) {
+	for (targ_lun_id = 0, num_filled = 0;
+	    targ_lun_id < num_port_luns && num_filled < num_luns;
+	    targ_lun_id++) {
 		lun_id = ctl_lun_map_from_port(port, targ_lun_id);
 		if (lun_id == UINT32_MAX)
 			continue;

Modified: stable/11/sys/cam/ctl/ctl_frontend.c
==============================================================================
--- stable/11/sys/cam/ctl/ctl_frontend.c	Sat Jan 21 08:32:56 2017	(r312575)
+++ stable/11/sys/cam/ctl/ctl_frontend.c	Sat Jan 21 08:33:44 2017	(r312576)
@@ -315,7 +315,7 @@ ctl_port_online(struct ctl_port *port)
 
 	if (port->lun_enable != NULL) {
 		if (port->lun_map) {
-			for (l = 0; l < CTL_MAX_LUNS; l++) {
+			for (l = 0; l < port->lun_map_size; l++) {
 				if (ctl_lun_map_from_port(port, l) ==
 				    UINT32_MAX)
 					continue;
@@ -359,7 +359,7 @@ ctl_port_offline(struct ctl_port *port)
 		port->port_offline(port->onoff_arg);
 	if (port->lun_disable != NULL) {
 		if (port->lun_map) {
-			for (l = 0; l < CTL_MAX_LUNS; l++) {
+			for (l = 0; l < port->lun_map_size; l++) {
 				if (ctl_lun_map_from_port(port, l) ==
 				    UINT32_MAX)
 					continue;

Modified: stable/11/sys/cam/ctl/ctl_frontend.h
==============================================================================
--- stable/11/sys/cam/ctl/ctl_frontend.h	Sat Jan 21 08:32:56 2017	(r312575)
+++ stable/11/sys/cam/ctl/ctl_frontend.h	Sat Jan 21 08:33:44 2017	(r312576)
@@ -225,6 +225,7 @@ struct ctl_port {
 	void		*onoff_arg;		/* passed to CTL */
 	lun_func_t	lun_enable;		/* passed to CTL */
 	lun_func_t	lun_disable;		/* passed to CTL */
+	int		lun_map_size;		/* passed to CTL */
 	uint32_t	*lun_map;		/* passed to CTL */
 	void		*targ_lun_arg;		/* passed to CTL */
 	void		(*fe_datamove)(union ctl_io *io); /* passed to CTL */

Modified: stable/11/sys/cam/ctl/ctl_io.h
==============================================================================
--- stable/11/sys/cam/ctl/ctl_io.h	Sat Jan 21 08:32:56 2017	(r312575)
+++ stable/11/sys/cam/ctl/ctl_io.h	Sat Jan 21 08:33:44 2017	(r312576)
@@ -365,7 +365,7 @@ struct ctl_taskio {
 /*
  * HA link messages.
  */
-#define	CTL_HA_VERSION		1
+#define	CTL_HA_VERSION		2
 
 /*
  * Used for CTL_MSG_LOGIN.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701210833.v0L8XjFN020815>