<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.2900.3243" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT face=Arial size=2><SPAN class=066093510-11062008>Here presented a 
patch, improving  the time of handling events like port state 
change.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN 
class=066093510-11062008></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=066093510-11062008>The patch replaces 
reading gids and pkeys one-by-one by reading them by chunks as MTHCA driver 
does.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Index: 
hw/mlx4/kernel/bus/core/cache.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/core/cache.c (revision 1259)<BR>+++ 
hw/mlx4/kernel/bus/core/cache.c (working copy)<BR>@@ -247,22 +247,30 
@@<BR> <BR>  gid_cache->table_len = 
tprops->gid_tbl_len;<BR> <BR>- for (i = 0; i < 
pkey_cache->table_len; ++i) {<BR>-  ret = ib_query_pkey(device, 
port, (u16)i, pkey_cache->table + i);<BR>+ for (i = 0; i < 
pkey_cache->table_len; i+=32) {<BR>+  __be16 
pkey_chunk[32];<BR>+  int size;<BR>+  ret = 
ib_query_pkey_chunk(device, port, (u16)i, pkey_chunk);<BR>   if 
(ret) {<BR>-   printk(KERN_WARNING "ib_query_pkey failed (%d) for 
%s (index %d)\n",<BR>+   printk(KERN_WARNING "ib_query_pkey_chunk 
failed (%d) for %s (index 
%d)\n",<BR>           ret, 
device->name, i);<BR>    goto 
err;<BR>   }<BR>+  size = min(32, 
pkey_cache->table_len - 
i);<BR>+  RtlCopyMemory(pkey_cache->table + i, pkey_chunk, 
size*sizeof(u16));<BR>  }<BR> <BR>- for (i = 0; i < 
gid_cache->table_len; ++i) {<BR>-  ret = ib_query_gid(device, port, 
i, gid_cache->table + i);<BR>+ for (i = 0; i < 
gid_cache->table_len; i+=8) {<BR>+  union ib_gid 
gid_chunk[8];<BR>+  int size;<BR>+  ret = 
ib_query_gid_chunk(device, port, i, gid_chunk);<BR>   if (ret) 
{<BR>-   printk(KERN_WARNING "ib_query_gid failed (%d) for %s 
(index %d)\n",<BR>+   printk(KERN_WARNING "ib_query_gid_chunk 
failed (%d) for %s (index 
%d)\n",<BR>           ret, 
device->name, i);<BR>    goto 
err;<BR>   }<BR>+  size = min(8, 
gid_cache->table_len - i);<BR>+  RtlCopyMemory(gid_cache->table 
+ i, gid_chunk, size*sizeof(union 
ib_gid));<BR>  }<BR> <BR>  write_lock_irq(&device->cache.lock);<BR>Index: 
hw/mlx4/kernel/bus/core/device.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/core/device.c (revision 1256)<BR>+++ 
hw/mlx4/kernel/bus/core/device.c (working copy)<BR>@@ -71,8 +71,8 
@@<BR>  } mandatory_table[] = 
{<BR>   IB_MANDATORY_FUNC(query_device),<BR>   IB_MANDATORY_FUNC(query_port),<BR>-  IB_MANDATORY_FUNC(query_pkey),<BR>-  IB_MANDATORY_FUNC(query_gid),<BR>+  IB_MANDATORY_FUNC(query_pkey_chunk),<BR>+  IB_MANDATORY_FUNC(query_gid_chunk),<BR>   IB_MANDATORY_FUNC(alloc_pd),<BR>   IB_MANDATORY_FUNC(dealloc_pd),<BR>   IB_MANDATORY_FUNC(create_ah),<BR>@@ 
-566,36 +566,36 
@@<BR> EXPORT_SYMBOL(ib_query_port);<BR> <BR> /**<BR>- * 
ib_query_gid - Get GID table entry<BR>+ * ib_query_gid_chunk - Get a chunk of 
GID table entries<BR>  * @device:Device to query<BR>  * @port_num:Port 
number to query<BR>  * @index:GID table index to query<BR>- * @gid:Returned 
GID<BR>+ * @gid:Returned GIDs chunk<BR>  *<BR>- * ib_query_gid() fetches 
the specified GID table entry.<BR>+ * ib_query_gid_chunk() fetches the specified 
GID table enties chunk.<BR>  */<BR>-int ib_query_gid(struct ib_device 
*device,<BR>-   u8 port_num, int index, union ib_gid *gid)<BR>+int 
ib_query_gid_chunk(struct ib_device *device,<BR>+   u8 port_num, int 
index, union ib_gid gid[8])<BR> {<BR>- return 
device->query_gid(device, port_num, index, gid);<BR>+ return 
device->query_gid_chunk(device, port_num, index, 
gid);<BR> }<BR>-EXPORT_SYMBOL(ib_query_gid);<BR>+EXPORT_SYMBOL(ib_query_gid_chunk);<BR> <BR> /**<BR>- 
* ib_query_pkey - Get P_Key table entry<BR>+ * ib_query_pkey_chunk - Get a chunk 
of  P_Key table entries<BR>  * @device:Device to query<BR>  * 
@port_num:Port number to query<BR>  * @index:P_Key table index to 
query<BR>- * @pkey:Returned P_Key<BR>+ * @pkey:Returned P_Keys chunk<BR>  
*<BR>- * ib_query_pkey() fetches the specified P_Key table entry.<BR>+ * 
ib_query_pkey_chunk() fetches the specified P_Key table entries chunk.<BR>  
*/<BR>-int ib_query_pkey(struct ib_device *device,<BR>-    u8 
port_num, u16 index, u16 *pkey)<BR>+int ib_query_pkey_chunk(struct ib_device 
*device,<BR>+    u8 port_num, u16 index, __be16 
pkey[32])<BR> {<BR>- return device->query_pkey(device, port_num, 
index, pkey);<BR>+ return device->query_pkey_chunk(device, port_num, 
index, 
pkey);<BR> }<BR>-EXPORT_SYMBOL(ib_query_pkey);<BR>+EXPORT_SYMBOL(ib_query_pkey_chunk);<BR> <BR> /**<BR>  
* ib_modify_device - Change IB device attributes<BR>@@ -650,19 +650,22 
@@<BR> int ib_find_gid(struct ib_device *device, union ib_gid 
*gid,<BR>   u8 *port_num, u16 *index)<BR> {<BR>- union 
ib_gid tmp_gid;<BR>- int ret, port, i;<BR>+ int ret, port, i, 
j;<BR>+ union ib_gid tmp_gid[8];<BR> <BR>  for (port = 
start_port(device); port <= end_port(device); ++port) {<BR>-  for 
(i = 0; i < device->gid_tbl_len[port - start_port(device)]; ++i) 
{<BR>-   ret = ib_query_gid(device, (u8)port, i, 
&tmp_gid);<BR>+  for (i = 0; i < device->gid_tbl_len[port - 
start_port(device)]; i+=8) {<BR>+   ret = 
ib_query_gid_chunk(device, (u8)port, i, tmp_gid);<BR>    if 
(ret)<BR>     return ret;<BR>-   if 
(!memcmp(&tmp_gid, gid, sizeof *gid)) 
{<BR>-    *port_num = 
(u8)port;<BR>-    if 
(index)<BR>-     *index = 
(u16)i;<BR>-    return 0;<BR>+<BR>+   for (j 
= 0; j < 8; ++j) {<BR>+    if (!memcmp(&tmp_gid[j], 
gid, sizeof *gid)) {<BR>+     *port_num = 
(u8)port;<BR>+     if 
(index)<BR>+      *index = 
(u16)(i+j);<BR>+     return 
0;<BR>+    }<BR>    }<BR>   }<BR>  }<BR>@@ 
-680,19 +683,21 @@<BR>  * @index: The index into the PKey table where the 
PKey was found.<BR>  */<BR> int ib_find_pkey(struct ib_device 
*device,<BR>-   u8 port_num, u16 pkey, u16 *index)<BR>+   u8 
port_num, __be16 pkey, u16 *index)<BR> {<BR>- int ret, 
i;<BR>- u16 tmp_pkey;<BR>+ int ret, i, j;<BR>+ __be16 
tmp_pkey[32];<BR> <BR>- for (i = 0; i < 
device->pkey_tbl_len[port_num - start_port(device)]; ++i) 
{<BR>-  ret = ib_query_pkey(device, port_num, (u16)i, 
&tmp_pkey);<BR>+ for (i = 0; i < device->pkey_tbl_len[port_num - 
start_port(device)]; i+=32) {<BR>+  ret = ib_query_pkey_chunk(device, 
port_num, (u16)i, tmp_pkey);<BR>   if 
(ret)<BR>    return ret;<BR> <BR>-  if ((pkey 
& 0x7fff) == (tmp_pkey & 0x7fff)) {<BR>-   *index = 
(u16)i;<BR>-   return 0;<BR>+  for (j = 0; j < 32; 
++j) {<BR>+   if ((pkey & 0x7fff) == (tmp_pkey[j] & 
0x7fff)) {<BR>+    *index = 
(u16)(i+j);<BR>+    return 
0;<BR>+   }<BR>   }<BR>  }<BR> <BR>Index: 
hw/mlx4/kernel/bus/ib/main.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/ib/main.c (revision 1259)<BR>+++ 
hw/mlx4/kernel/bus/ib/main.c (working copy)<BR>@@ -172,11 +172,12 
@@<BR>  return err;<BR> }<BR> <BR>-static int 
mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int 
index,<BR>-        union ib_gid 
*gid)<BR>+static int mlx4_ib_query_gid_chunk(struct ib_device *ibdev, u8 port, 
int index,<BR>+        union ib_gid 
gid[8])<BR> {<BR>  struct ib_smp *in_mad  = 
NULL;<BR>  struct ib_smp *out_mad = 
NULL;<BR>+ __be64 subnet_prefix;<BR>  int err = 
-ENOMEM;<BR> <BR>  in_mad  = kzalloc(sizeof *in_mad, 
GFP_KERNEL);<BR>@@ -192,7 +193,7 @@<BR>  if 
(err)<BR>   goto out;<BR> <BR>- memcpy(gid->raw, 
out_mad->data + 8, 8);<BR>+ memcpy(&subnet_prefix, out_mad->data 
+ 8, 
8);<BR> <BR>  init_query_mad(in_mad);<BR>  in_mad->attr_id  
= IB_SMP_ATTR_GUID_INFO;<BR>@@ -202,7 +203,14 @@<BR>  if 
(err)<BR>   goto out;<BR> <BR>- memcpy(gid->raw + 8, 
out_mad->data + (index % 8) * 8, 8);<BR>+ { // copy the 
results<BR>+  int i;<BR>+  __be64 *guid = (__be64 
*)out_mad->data;<BR>+  for (i=0; i<8; ++i) 
{<BR>+   gid[i].global.subnet_prefix = 
subnet_prefix;<BR>+   gid[i].global.interface_id = 
guid[i];<BR>+  }<BR>+ }<BR> <BR> out:<BR>  kfree(in_mad);<BR>@@ 
-210,8 +218,8 @@<BR>  return err;<BR> }<BR> <BR>-static int 
mlx4_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 
index,<BR>-         u16 
*pkey)<BR>+static int mlx4_ib_query_pkey_chunk(struct ib_device *ibdev, u8 port, 
u16 index,<BR>+        __be16 
pkey[32])<BR> {<BR>  struct ib_smp *in_mad  = 
NULL;<BR>  struct ib_smp *out_mad = NULL;<BR>@@ -230,7 +238,12 
@@<BR>  if (err)<BR>   goto 
out;<BR> <BR>- *pkey = ((__be16 *) out_mad->data)[index % 
32];<BR>+ { // copy the results<BR>+  int 
i;<BR>+  __be16 *pkey_chunk = (__be16 
*)out_mad->data;<BR>+  for (i=0; i<32; ++i) 
<BR>+   pkey[i] = 
pkey_chunk[i];<BR>+ }<BR> <BR> out:<BR>  kfree(in_mad);<BR>@@ 
-502,8 +515,8 @@<BR>  ibdev->ib_dev.uverbs_abi_ver = 
MLX4_IB_UVERBS_ABI_VERSION;<BR>  ibdev->ib_dev.query_device = 
mlx4_ib_query_device;<BR>  ibdev->ib_dev.query_port = 
mlx4_ib_query_port;<BR>- ibdev->ib_dev.query_gid  = 
mlx4_ib_query_gid;<BR>- ibdev->ib_dev.query_pkey = 
mlx4_ib_query_pkey;<BR>+ ibdev->ib_dev.query_gid_chunk = 
mlx4_ib_query_gid_chunk;<BR>+ ibdev->ib_dev.query_pkey_chunk = 
mlx4_ib_query_pkey_chunk;<BR>  ibdev->ib_dev.modify_device = 
mlx4_ib_modify_device;<BR>  ibdev->ib_dev.modify_port = 
mlx4_ib_modify_port;<BR>  ibdev->ib_dev.alloc_ucontext = 
mlx4_ib_alloc_ucontext;<BR>Index: 
hw/mlx4/kernel/bus/inc/ib_verbs.h<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/inc/ib_verbs.h (revision 1256)<BR>+++ 
hw/mlx4/kernel/bus/inc/ib_verbs.h (working copy)<BR>@@ -889,11 +889,11 
@@<BR>  int             
(*query_port)(struct ib_device 
*device,<BR>        u8 
port_num,<BR>        struct ib_port_attr 
*port_attr);<BR>- int             
(*query_gid)(struct ib_device 
*device,<BR>+ int             
(*query_gid_chunk)(struct ib_device 
*device,<BR>       u8 port_num, int 
index,<BR>-      union ib_gid 
*gid);<BR>- int             
(*query_pkey)(struct ib_device *device,<BR>-       
u8 port_num, u16 index, u16 
*pkey);<BR>+      union ib_gid 
gid[8]);<BR>+ int             
(*query_pkey_chunk)(struct ib_device 
*device,<BR>+       u8 port_num, u16 index, __be16 
pkey[32]);<BR>  int             
(*modify_device)(struct ib_device 
*device,<BR>           int 
device_modify_mask,<BR>           
struct ib_device_modify *device_modify);<BR>@@ -1096,11 +1096,11 @@<BR> int 
ib_query_port(struct ib_device *device,<BR>     u8 port_num, 
struct ib_port_attr *port_attr);<BR> <BR>-int ib_query_gid(struct ib_device 
*device,<BR>-   u8 port_num, int index, union ib_gid *gid);<BR>+int 
ib_query_gid_chunk(struct ib_device *device,<BR>+   u8 port_num, int 
index, union ib_gid gid[8]);<BR> <BR>-int ib_query_pkey(struct ib_device 
*device,<BR>-    u8 port_num, u16 index, u16 *pkey);<BR>+int 
ib_query_pkey_chunk(struct ib_device *device,<BR>+    u8 
port_num, u16 index, __be16 pkey[32]);<BR> <BR> int 
ib_modify_device(struct ib_device 
*device,<BR>        int 
device_modify_mask,<BR>@@ -1114,7 +1114,7 @@<BR>   u8 *port_num, 
u16 *index);<BR> <BR> int ib_find_pkey(struct ib_device 
*device,<BR>-   u8 port_num, u16 pkey, u16 *index);<BR>+   
u8 port_num, __be16 pkey, u16 *index);<BR> <BR> /**<BR>  * 
ib_alloc_pd - Allocates an unused protection 
domain.<BR></FONT></DIV><div>

<p><span style='color:#1F497D'> </span><span
style='font-size:18.0pt;font-family:Webdings;color:green'>P</span><span
style='font-size:18.0pt;font-family:"Courier New";color:green'> </span><span
style='font-size:10.0pt;font-family:"Arial","sans-serif";color:blue'> </span><span
style='font-size:10.0pt;font-family:"Arial","sans-serif";color:green'>Please consider
the environment before printing this e-mail or its attachment(s)</span><span
style='font-size:10.0pt;font-family:"Arial","sans-serif";color:blue'> </span><span
style='color:navy'><o:p></o:p></span></p>

</div><div style="color:#999999;font-size:11px;font-family:verdana"><br>Disclaimer added by <b>CodeTwo Exchange Rules</b><br><a href="http://www.codetwo.com">www.codetwo.com</a></div>
<!--418FEECD7B41410cA6AF47547865A7D9-->
<br></BODY></HTML>