[ofw] improve the time of handling events like port state change
Leonid Keller
leonid at mellanox.co.il
Wed Jun 11 03:39:40 PDT 2008
Here presented a patch, improving the time of handling events like port
state change.
The patch replaces reading gids and pkeys one-by-one by reading them by
chunks as MTHCA driver does.
Index: hw/mlx4/kernel/bus/core/cache.c
===================================================================
--- hw/mlx4/kernel/bus/core/cache.c (revision 1259)
+++ hw/mlx4/kernel/bus/core/cache.c (working copy)
@@ -247,22 +247,30 @@
gid_cache->table_len = tprops->gid_tbl_len;
- for (i = 0; i < pkey_cache->table_len; ++i) {
- ret = ib_query_pkey(device, port, (u16)i, pkey_cache->table + i);
+ for (i = 0; i < pkey_cache->table_len; i+=32) {
+ __be16 pkey_chunk[32];
+ int size;
+ ret = ib_query_pkey_chunk(device, port, (u16)i, pkey_chunk);
if (ret) {
- printk(KERN_WARNING "ib_query_pkey failed (%d) for %s (index %d)\n",
+ printk(KERN_WARNING "ib_query_pkey_chunk failed (%d) for %s (index
%d)\n",
ret, device->name, i);
goto err;
}
+ size = min(32, pkey_cache->table_len - i);
+ RtlCopyMemory(pkey_cache->table + i, pkey_chunk, size*sizeof(u16));
}
- for (i = 0; i < gid_cache->table_len; ++i) {
- ret = ib_query_gid(device, port, i, gid_cache->table + i);
+ for (i = 0; i < gid_cache->table_len; i+=8) {
+ union ib_gid gid_chunk[8];
+ int size;
+ ret = ib_query_gid_chunk(device, port, i, gid_chunk);
if (ret) {
- printk(KERN_WARNING "ib_query_gid failed (%d) for %s (index %d)\n",
+ printk(KERN_WARNING "ib_query_gid_chunk failed (%d) for %s (index
%d)\n",
ret, device->name, i);
goto err;
}
+ size = min(8, gid_cache->table_len - i);
+ RtlCopyMemory(gid_cache->table + i, gid_chunk, size*sizeof(union
ib_gid));
}
write_lock_irq(&device->cache.lock);
Index: hw/mlx4/kernel/bus/core/device.c
===================================================================
--- hw/mlx4/kernel/bus/core/device.c (revision 1256)
+++ hw/mlx4/kernel/bus/core/device.c (working copy)
@@ -71,8 +71,8 @@
} mandatory_table[] = {
IB_MANDATORY_FUNC(query_device),
IB_MANDATORY_FUNC(query_port),
- IB_MANDATORY_FUNC(query_pkey),
- IB_MANDATORY_FUNC(query_gid),
+ IB_MANDATORY_FUNC(query_pkey_chunk),
+ IB_MANDATORY_FUNC(query_gid_chunk),
IB_MANDATORY_FUNC(alloc_pd),
IB_MANDATORY_FUNC(dealloc_pd),
IB_MANDATORY_FUNC(create_ah),
@@ -566,36 +566,36 @@
EXPORT_SYMBOL(ib_query_port);
/**
- * ib_query_gid - Get GID table entry
+ * ib_query_gid_chunk - Get a chunk of GID table entries
* @device:Device to query
* @port_num:Port number to query
* @index:GID table index to query
- * @gid:Returned GID
+ * @gid:Returned GIDs chunk
*
- * ib_query_gid() fetches the specified GID table entry.
+ * ib_query_gid_chunk() fetches the specified GID table enties chunk.
*/
-int ib_query_gid(struct ib_device *device,
- u8 port_num, int index, union ib_gid *gid)
+int ib_query_gid_chunk(struct ib_device *device,
+ u8 port_num, int index, union ib_gid gid[8])
{
- return device->query_gid(device, port_num, index, gid);
+ return device->query_gid_chunk(device, port_num, index, gid);
}
-EXPORT_SYMBOL(ib_query_gid);
+EXPORT_SYMBOL(ib_query_gid_chunk);
/**
- * ib_query_pkey - Get P_Key table entry
+ * ib_query_pkey_chunk - Get a chunk of P_Key table entries
* @device:Device to query
* @port_num:Port number to query
* @index:P_Key table index to query
- * @pkey:Returned P_Key
+ * @pkey:Returned P_Keys chunk
*
- * ib_query_pkey() fetches the specified P_Key table entry.
+ * ib_query_pkey_chunk() fetches the specified P_Key table entries
chunk.
*/
-int ib_query_pkey(struct ib_device *device,
- u8 port_num, u16 index, u16 *pkey)
+int ib_query_pkey_chunk(struct ib_device *device,
+ u8 port_num, u16 index, __be16 pkey[32])
{
- return device->query_pkey(device, port_num, index, pkey);
+ return device->query_pkey_chunk(device, port_num, index, pkey);
}
-EXPORT_SYMBOL(ib_query_pkey);
+EXPORT_SYMBOL(ib_query_pkey_chunk);
/**
* ib_modify_device - Change IB device attributes
@@ -650,19 +650,22 @@
int ib_find_gid(struct ib_device *device, union ib_gid *gid,
u8 *port_num, u16 *index)
{
- union ib_gid tmp_gid;
- int ret, port, i;
+ int ret, port, i, j;
+ union ib_gid tmp_gid[8];
for (port = start_port(device); port <= end_port(device); ++port) {
- for (i = 0; i < device->gid_tbl_len[port - start_port(device)]; ++i)
{
- ret = ib_query_gid(device, (u8)port, i, &tmp_gid);
+ for (i = 0; i < device->gid_tbl_len[port - start_port(device)]; i+=8)
{
+ ret = ib_query_gid_chunk(device, (u8)port, i, tmp_gid);
if (ret)
return ret;
- if (!memcmp(&tmp_gid, gid, sizeof *gid)) {
- *port_num = (u8)port;
- if (index)
- *index = (u16)i;
- return 0;
+
+ for (j = 0; j < 8; ++j) {
+ if (!memcmp(&tmp_gid[j], gid, sizeof *gid)) {
+ *port_num = (u8)port;
+ if (index)
+ *index = (u16)(i+j);
+ return 0;
+ }
}
}
}
@@ -680,19 +683,21 @@
* @index: The index into the PKey table where the PKey was found.
*/
int ib_find_pkey(struct ib_device *device,
- u8 port_num, u16 pkey, u16 *index)
+ u8 port_num, __be16 pkey, u16 *index)
{
- int ret, i;
- u16 tmp_pkey;
+ int ret, i, j;
+ __be16 tmp_pkey[32];
- for (i = 0; i < device->pkey_tbl_len[port_num - start_port(device)];
++i) {
- ret = ib_query_pkey(device, port_num, (u16)i, &tmp_pkey);
+ for (i = 0; i < device->pkey_tbl_len[port_num - start_port(device)];
i+=32) {
+ ret = ib_query_pkey_chunk(device, port_num, (u16)i, tmp_pkey);
if (ret)
return ret;
- if ((pkey & 0x7fff) == (tmp_pkey & 0x7fff)) {
- *index = (u16)i;
- return 0;
+ for (j = 0; j < 32; ++j) {
+ if ((pkey & 0x7fff) == (tmp_pkey[j] & 0x7fff)) {
+ *index = (u16)(i+j);
+ return 0;
+ }
}
}
Index: hw/mlx4/kernel/bus/ib/main.c
===================================================================
--- hw/mlx4/kernel/bus/ib/main.c (revision 1259)
+++ hw/mlx4/kernel/bus/ib/main.c (working copy)
@@ -172,11 +172,12 @@
return err;
}
-static int mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int
index,
- union ib_gid *gid)
+static int mlx4_ib_query_gid_chunk(struct ib_device *ibdev, u8 port,
int index,
+ union ib_gid gid[8])
{
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
+ __be64 subnet_prefix;
int err = -ENOMEM;
in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
@@ -192,7 +193,7 @@
if (err)
goto out;
- memcpy(gid->raw, out_mad->data + 8, 8);
+ memcpy(&subnet_prefix, out_mad->data + 8, 8);
init_query_mad(in_mad);
in_mad->attr_id = IB_SMP_ATTR_GUID_INFO;
@@ -202,7 +203,14 @@
if (err)
goto out;
- memcpy(gid->raw + 8, out_mad->data + (index % 8) * 8, 8);
+ { // copy the results
+ int i;
+ __be64 *guid = (__be64 *)out_mad->data;
+ for (i=0; i<8; ++i) {
+ gid[i].global.subnet_prefix = subnet_prefix;
+ gid[i].global.interface_id = guid[i];
+ }
+ }
out:
kfree(in_mad);
@@ -210,8 +218,8 @@
return err;
}
-static int mlx4_ib_query_pkey(struct ib_device *ibdev, u8 port, u16
index,
- u16 *pkey)
+static int mlx4_ib_query_pkey_chunk(struct ib_device *ibdev, u8 port,
u16 index,
+ __be16 pkey[32])
{
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
@@ -230,7 +238,12 @@
if (err)
goto out;
- *pkey = ((__be16 *) out_mad->data)[index % 32];
+ { // copy the results
+ int i;
+ __be16 *pkey_chunk = (__be16 *)out_mad->data;
+ for (i=0; i<32; ++i)
+ pkey[i] = pkey_chunk[i];
+ }
out:
kfree(in_mad);
@@ -502,8 +515,8 @@
ibdev->ib_dev.uverbs_abi_ver = MLX4_IB_UVERBS_ABI_VERSION;
ibdev->ib_dev.query_device = mlx4_ib_query_device;
ibdev->ib_dev.query_port = mlx4_ib_query_port;
- ibdev->ib_dev.query_gid = mlx4_ib_query_gid;
- ibdev->ib_dev.query_pkey = mlx4_ib_query_pkey;
+ ibdev->ib_dev.query_gid_chunk = mlx4_ib_query_gid_chunk;
+ ibdev->ib_dev.query_pkey_chunk = mlx4_ib_query_pkey_chunk;
ibdev->ib_dev.modify_device = mlx4_ib_modify_device;
ibdev->ib_dev.modify_port = mlx4_ib_modify_port;
ibdev->ib_dev.alloc_ucontext = mlx4_ib_alloc_ucontext;
Index: hw/mlx4/kernel/bus/inc/ib_verbs.h
===================================================================
--- hw/mlx4/kernel/bus/inc/ib_verbs.h (revision 1256)
+++ hw/mlx4/kernel/bus/inc/ib_verbs.h (working copy)
@@ -889,11 +889,11 @@
int (*query_port)(struct ib_device *device,
u8 port_num,
struct ib_port_attr *port_attr);
- int (*query_gid)(struct ib_device *device,
+ int (*query_gid_chunk)(struct ib_device *device,
u8 port_num, int index,
- union ib_gid *gid);
- int (*query_pkey)(struct ib_device *device,
- u8 port_num, u16 index, u16 *pkey);
+ union ib_gid gid[8]);
+ int (*query_pkey_chunk)(struct ib_device *device,
+ u8 port_num, u16 index, __be16 pkey[32]);
int (*modify_device)(struct ib_device *device,
int device_modify_mask,
struct ib_device_modify *device_modify);
@@ -1096,11 +1096,11 @@
int ib_query_port(struct ib_device *device,
u8 port_num, struct ib_port_attr *port_attr);
-int ib_query_gid(struct ib_device *device,
- u8 port_num, int index, union ib_gid *gid);
+int ib_query_gid_chunk(struct ib_device *device,
+ u8 port_num, int index, union ib_gid gid[8]);
-int ib_query_pkey(struct ib_device *device,
- u8 port_num, u16 index, u16 *pkey);
+int ib_query_pkey_chunk(struct ib_device *device,
+ u8 port_num, u16 index, __be16 pkey[32]);
int ib_modify_device(struct ib_device *device,
int device_modify_mask,
@@ -1114,7 +1114,7 @@
u8 *port_num, u16 *index);
int ib_find_pkey(struct ib_device *device,
- u8 port_num, u16 pkey, u16 *index);
+ u8 port_num, __be16 pkey, u16 *index);
/**
* ib_alloc_pd - Allocates an unused protection domain.
--
Leonid Keller
Mellanox Technologies LTD.
SW- Windows
Phone: +972 (4) 909 7200 (ext 372)
Mobile: +972 (54) 464 7702
E-mail: leonid at mellanox.co.il
----------------------------------------------------------------------
Emails belong on computers, trees belong in forests; if you must print
this, do it on recycled paper.
http://www.greenpeace.org/international/
----------------------------------------------------------------------
Disclaimer added by CodeTwo Exchange Rules
http://www.codetwo.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080611/33d112ac/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: port_state_change.patch
Type: application/octet-stream
Size: 9611 bytes
Desc: port_state_change.patch
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080611/33d112ac/attachment.obj>
More information about the ofw
mailing list