Skip to content

Commit

Permalink
Decouple limits on number of LUNs per port and LUs per CTL.
Browse files Browse the repository at this point in the history
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.

MFC after:	2 weeks


git-svn-id: svn+ssh://svn.freebsd.org/base/head@310635 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
  • Loading branch information
mav committed Dec 27, 2016
1 parent 72eba96 commit 364c1d2
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 28 deletions.
70 changes: 45 additions & 25 deletions sys/cam/ctl/ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,9 @@ SYSCTL_INT(_kern_cam_ctl, OID_AUTO, worker_threads, CTLFLAG_RDTUN,
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),
Expand Down Expand Up @@ -826,7 +829,7 @@ ctl_isc_announce_port(struct ctl_port *port)
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)
Expand All @@ -846,7 +849,7 @@ ctl_isc_announce_port(struct ctl_port *port)
"%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;
Expand Down Expand Up @@ -1155,19 +1158,25 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
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);
Expand All @@ -1182,7 +1191,7 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
}
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);
Expand All @@ -1197,7 +1206,7 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
}
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);
Expand Down Expand Up @@ -3295,7 +3304,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,

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;
Expand Down Expand Up @@ -3375,21 +3384,20 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
}
}
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 &&
softc->ctl_luns[lm->lun] != NULL)
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;
Expand Down Expand Up @@ -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)
Expand All @@ -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) {
Expand All @@ -3492,6 +3506,8 @@ ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun)
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) {
Expand All @@ -3507,7 +3523,7 @@ ctl_lun_map_unset(struct ctl_port *port, uint32_t plun)
{
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;
Expand All @@ -3525,8 +3541,10 @@ ctl_lun_map_from_port(struct ctl_port *port, uint32_t lun_id)

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]);
}

Expand All @@ -3539,7 +3557,7 @@ ctl_lun_map_to_port(struct ctl_port *port, uint32_t lun_id)
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);
}
Expand Down Expand Up @@ -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;
Expand All @@ -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++;
}
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions sys/cam/ctl/ctl_frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions sys/cam/ctl/ctl_frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion sys/cam/ctl/ctl_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 364c1d2

Please sign in to comment.