Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2016-06-09 19:15:46 -07:00
4 changed files with 177 additions and 10 deletions
+28
View File
@@ -1827,6 +1827,34 @@ benefit from SCST VAAI implementation. Those actions described in the
implementation notes below. For vdisk and fileio_tgt handlers they have
already been implemented.
IMPORTANT: To use EXTENDED COPY command between LUNs (datastores) they all
========= MUST have the same PRODUCT IDENTIFICATION INQUIRY field. By
default, to simplify remote devices identification, SCST uses
vdisk names as PRODUCT IDENTIFICATION, so SCST devices look
differently from the initiators. However, for some reasons,
VMware does not use EXTENDED COPY between LUNs with different
PRODUCT IDENTIFICATION. Thus, to be able to use full VAAI in
your VMware setups you must manually set PRODUCT
IDENTIFICATION for all your VMware LUNs to the same value,
for instance, "SCST", via using "prod_id" attribute. It could
be done either by adding "prod_id" attribute to scstadmin
scst.conf, or by directly writing to SCST sysfs attribute.
For example:
HANDLER vdisk_blockio {
DEVICE blockio1 {
filename /dev/sda5
prod_id SCST
}
or
echo SCST >/sys/kernel/scst_tgt/devices/blockio1/prod_id
correspondingly.
Note, this prod_id modification must be done on all
datastores BEFORE VMware connects to them.
Implementation notes
....................
+28
View File
@@ -1680,6 +1680,34 @@ benefit from SCST VAAI implementation. Those actions described in the
implementation notes below. For vdisk and fileio_tgt handlers they have
already been implemented.
IMPORTANT: To use EXTENDED COPY command between LUNs (datastores) they all
========= MUST have the same PRODUCT IDENTIFICATION INQUIRY field. By
default, to simplify remote devices identification, SCST uses
vdisk names as PRODUCT IDENTIFICATION, so SCST devices look
differently from the initiators. However, for some reasons,
VMware does not use EXTENDED COPY between LUNs with different
PRODUCT IDENTIFICATION. Thus, to be able to use full VAAI in
your VMware setups you must manually set PRODUCT
IDENTIFICATION for all your VMware LUNs to the same value,
for instance, "SCST", via using "prod_id" attribute. It could
be done either by adding "prod_id" attribute to scstadmin
scst.conf, or by directly writing to SCST sysfs attribute.
For example:
HANDLER vdisk_blockio {
DEVICE blockio1 {
filename /dev/sda5
prod_id SCST
}
or
echo SCST >/sys/kernel/scst_tgt/devices/blockio1/prod_id
correspondingly.
Note, this prod_id modification must be done on all
datastores BEFORE VMware connects to them.
Implementation notes
....................
+119 -9
View File
@@ -90,7 +90,7 @@
#define SRPT_PROC_TRACE_LEVEL_NAME "trace_level"
#endif
#define SRPT_ID_STRING "SCST SRP target"
#define DEFAULT_SRPT_ID_STRING "SCST SRP target"
MODULE_AUTHOR("Vu Pham and Bart Van Assche");
MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol target "
@@ -419,7 +419,11 @@ static void srpt_get_class_port_info(struct ib_dm_mad *mad)
memset(cif, 0, sizeof(*cif));
cif->base_version = 1;
cif->class_version = 1;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)
cif->resp_time_value = 20;
#else
ib_set_cpi_resp_time(cif, 20);
#endif
mad->mad_hdr.status = 0;
}
@@ -480,7 +484,9 @@ static void srpt_get_ioc(struct srpt_port *sport, u32 slot,
send_queue_depth = min(SRPT_RQ_SIZE, sdev->dev_attr.max_qp_wr);
memset(iocp, 0, sizeof(*iocp));
strcpy(iocp->id_string, SRPT_ID_STRING);
mutex_lock(&sport->mutex);
strlcpy(iocp->id_string, sport->port_id, sizeof(iocp->id_string));
mutex_unlock(&sport->mutex);
iocp->guid = cpu_to_be64(srpt_service_guid);
iocp->vendor_id = cpu_to_be32(sdev->dev_attr.vendor_id);
iocp->device_id = cpu_to_be32(sdev->dev_attr.vendor_part_id);
@@ -4035,6 +4041,99 @@ out:
static struct kobj_attribute srpt_device_attr =
__ATTR(device, S_IRUGO, srpt_show_device, NULL);
/*
* The link layer names in this function match those used by the IB core.
* See also link_layer_show() in drivers/infiniband/core/sysfs.c
*/
static ssize_t srpt_show_link_layer(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct scst_tgt *scst_tgt = container_of(kobj, struct scst_tgt,
tgt_kobj);
struct srpt_port *sport = scst_tgt_get_tgt_priv(scst_tgt);
const char *lln = "Unknown";
int res = -E_TGT_PRIV_NOT_YET_SET;
if (!sport)
goto out;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) /* commit a3f5adaf4 */
switch (rdma_port_get_link_layer(sport->sdev->device, sport->port)) {
case IB_LINK_LAYER_INFINIBAND:
lln = "InfiniBand";
break;
case IB_LINK_LAYER_ETHERNET:
lln = "Ethernet";
break;
case IB_LINK_LAYER_UNSPECIFIED:
default:
break;
}
#endif
res = sprintf(buf, "%s\n", lln);
out:
return res;
}
static struct kobj_attribute srpt_link_layer_attr =
__ATTR(link_layer, S_IRUGO, srpt_show_link_layer, NULL);
static ssize_t show_port_id(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
struct scst_tgt *scst_tgt = container_of(kobj, struct scst_tgt,
tgt_kobj);
struct srpt_port *sport = scst_tgt_get_tgt_priv(scst_tgt);
int res = -E_TGT_PRIV_NOT_YET_SET;
if (!sport)
goto out;
mutex_lock(&sport->mutex);
snprintf(buf, PAGE_SIZE, "%s\n%s", sport->port_id,
strcmp(sport->port_id, DEFAULT_SRPT_ID_STRING) ?
SCST_SYSFS_KEY_MARK "\n" : "");
mutex_unlock(&sport->mutex);
res = strlen(buf);
out:
return res;
}
static ssize_t store_port_id(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count)
{
struct scst_tgt *scst_tgt = container_of(kobj, struct scst_tgt,
tgt_kobj);
struct srpt_port *sport = scst_tgt_get_tgt_priv(scst_tgt);
const char *end;
int res = -E_TGT_PRIV_NOT_YET_SET;
if (!sport)
goto out;
end = buf + count;
while (end > buf && isspace(((unsigned char *)end)[-1]))
--end;
res = -E2BIG;
if (end - buf >= sizeof(sport->port_id))
goto out;
mutex_lock(&sport->mutex);
sprintf(sport->port_id, "%.*s", (int)(end - buf), buf);
mutex_unlock(&sport->mutex);
res = count;
out:
return res;
}
static struct kobj_attribute srpt_port_id_attr =
__ATTR(port_id, S_IRUGO | S_IWUSR, show_port_id, store_port_id);
static ssize_t show_login_info(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
@@ -4071,6 +4170,8 @@ static struct kobj_attribute srpt_show_login_info_attr =
static const struct attribute *srpt_tgt_attrs[] = {
&srpt_show_comp_v_mask_attr.attr,
&srpt_device_attr.attr,
&srpt_link_layer_attr.attr,
&srpt_port_id_attr.attr,
&srpt_show_login_info_attr.attr,
NULL
};
@@ -4194,6 +4295,20 @@ static struct scst_proc_data srpt_log_proc_data = {
#endif /* CONFIG_SCST_PROC */
/* Note: the caller must have zero-initialized *@sport. */
static void srpt_init_sport(struct srpt_port *sport, struct ib_device *ib_dev)
{
int i;
INIT_LIST_HEAD(&sport->nexus_list);
init_waitqueue_head(&sport->ch_releaseQ);
mutex_init(&sport->mutex);
strlcpy(sport->port_id, DEFAULT_SRPT_ID_STRING,
sizeof(sport->port_id));
for (i = 0; i < ib_dev->num_comp_vectors; i++)
cpumask_set_cpu(i, &sport->comp_v_mask);
}
/**
* srpt_add_one() - Infiniband device addition callback function.
*/
@@ -4203,7 +4318,7 @@ static void srpt_add_one(struct ib_device *device)
struct srpt_device *sdev;
struct srpt_port *sport;
struct ib_srq_init_attr srq_attr;
int i, j, ret;
int i, ret;
pr_debug("device = %p, device->dma_ops = %p\n", device, device->dma_ops);
@@ -4325,12 +4440,7 @@ static void srpt_add_one(struct ib_device *device)
sport = &sdev->port[i - 1];
sport->sdev = sdev;
sport->port = i;
INIT_LIST_HEAD(&sport->nexus_list);
init_waitqueue_head(&sport->ch_releaseQ);
mutex_init(&sport->mutex);
sport->comp_vector = -1;
for (j = 0; j < sdev->device->num_comp_vectors; j++)
cpumask_set_cpu(j, &sport->comp_v_mask);
srpt_init_sport(sport, sdev->device);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) && !defined(BACKPORT_LINUX_WORKQUEUE_TO_2_6_19)
/*
* A vanilla 2.6.19 or older kernel without backported OFED
+2 -1
View File
@@ -343,7 +343,6 @@ enum rdma_ch_state {
* @pkey: P_Key of the IB partition for this SRP channel.
* @comp_vector: Completion vector assigned to the QP.
* @using_rdma_cm: Whether to use the RDMA/CM or the IB/CM.
* @processing_wait_list: Whether the I/O context wait list is being processed.
* @sess_name: SCST session name.
* @sess: SCST session information associated with this SRP channel.
*/
@@ -419,6 +418,7 @@ struct srpt_nexus {
* @comp_v_mask: Bitmask with one bit per allowed completion vector.
* @comp_vector: Completion vector from where searching will start.
* @enabled: Whether or not this SCST target is enabled.
* @port_id: ID String reported in IOControllerProfile replies.
*/
struct srpt_port {
struct srpt_device *sdev;
@@ -435,6 +435,7 @@ struct srpt_port {
cpumask_t comp_v_mask;
u8 comp_vector;
bool enabled;
u8 port_id[64];
};
/**