[ewg] [PATCH 5/5] RDMA/nes: a fix for problem of lack of HW limit checking for MG attach.

miroslaw.walukiewicz at intel.com miroslaw.walukiewicz at intel.com
Thu Dec 9 08:02:05 PST 2010


Now a HW limits for multicast address attach ro RAW QP are checked.
 the error is returned when application wants attaching more than possible
multicast groups.

Signed-off-by: Mirek Walukiewicz <miroslaw.walukiewicz at intel.com>
---

 kernel_patches/fixes/nes_0055_ima_multi_mg.patch |  129 ++++++++++++++++++++++
 1 files changed, 129 insertions(+), 0 deletions(-)
 create mode 100644 kernel_patches/fixes/nes_0055_ima_multi_mg.patch


diff --git a/kernel_patches/fixes/nes_0055_ima_multi_mg.patch b/kernel_patches/fixes/nes_0055_ima_multi_mg.patch
new file mode 100644
index 0000000..ab38c56
--- /dev/null
+++ b/kernel_patches/fixes/nes_0055_ima_multi_mg.patch
@@ -0,0 +1,129 @@
+diff --git a/drivers/infiniband/hw/nes/nes_ud.c b/drivers/infiniband/hw/nes/nes_ud.c
+index d0af571..a9ab971 100644
+--- a/drivers/infiniband/hw/nes/nes_ud.c
++++ b/drivers/infiniband/hw/nes/nes_ud.c
+@@ -60,6 +60,7 @@
+ #define NES_UD_CQE_NUM NES_NIC_WQ_SIZE
+ #define NES_UD_SKSQ_WAIT_TIMEOUT	100000
+ #define NES_UD_MAX_REG_CNT 128
++#define NES_UD_MAX_MCAST_PER_QP 40
+ 
+ #define NES_UD_MAX_ADAPTERS 4 /* number of supported interfaces for  RAW ETH */
+ 
+@@ -1400,20 +1401,76 @@ out:
+ 
+ }
+ 
+-/* function returns a number of allocated multicast entries in given adapter */
++/* function returns a number of QP with allocated multicast entries */
++/* in given adapter */
+ static int get_mcast_number_alloced(struct nes_ud_resources *pRsc)
+ {
+ 	int i;
+ 	int no = 0;
++	int cnt[NES_UD_MAX_NIC_CNT];
++
++	for (i = 0; i < NES_UD_MAX_NIC_CNT; i++)
++		cnt[i] = 0;
+ 
+ 	for (i = 0; i < NES_UD_MCAST_TBL_SZ; i++) {
+ 		if (pRsc->mcast[i].in_use != 0)
++			if (pRsc->mcast[i].owner)
++				cnt[pRsc->mcast[i].owner->rsc_idx]++;
++	}
++	for (i = 0; i <  NES_UD_MAX_NIC_CNT; i++)
++		if (cnt[i] != 0)
+ 			no++;
+ 
+-	}
+ 	return no;
+ }
+ 
++/*
++ * function returns a number of multicast groups subscribed to given Rsc
++ * Due to HW limitation it cannot exceeds 40.
++ */
++static int get_subscribed_mcast(struct nes_ud_resources *pRsc,
++				u8 addr0,
++				u8 addr1,
++				u8 addr2)
++{
++	int i, idx;
++	struct nes_ud_mcast cnt[NES_UD_MAX_MCAST_PER_QP];
++	int num_alloced = 0;
++	struct nes_ud_mcast *pMcast;
++
++	for (i = 0; i < NES_UD_MAX_MCAST_PER_QP; i++)
++		memset(&cnt[i], 0, sizeof(struct nes_ud_mcast));
++
++	/* create a list of MGroups subscribed by this Rsc */
++	for (i = 0; i < NES_UD_MCAST_TBL_SZ; i++) {
++		pMcast = &pRsc->mcast[i];
++		if (pMcast->in_use != 0) {
++			for (idx = 0; idx < num_alloced; idx++) {
++				if ((pMcast->addr[0] == cnt[idx].addr[0]) &&
++					(pMcast->addr[1] == cnt[idx].addr[1]) &&
++					(pMcast->addr[2] == cnt[idx].addr[2]))
++					break;
++			}
++			if (idx == num_alloced) {
++				cnt[idx].addr[0] = pMcast->addr[0];
++				cnt[idx].addr[1] = pMcast->addr[1];
++				cnt[idx].addr[2] = pMcast->addr[2];
++				num_alloced++;
++				if (num_alloced == NES_UD_MAX_MCAST_PER_QP)
++					break;
++			}
++		}
++	}
++	/* check id a new group will have a place in PFT */
++	for (i = 0; i < num_alloced; i++) {
++		if ((addr0 == cnt[i].addr[0]) &&
++			(addr1 == cnt[i].addr[1]) &&
++			(addr2 == cnt[i].addr[2]))
++				break;
++	}
++	return i;
++}
++
+ /* function subscribe a multicast group in the system - PFT modification */
+ int nes_ud_subscribe_mcast(struct nes_ud_file *file, union ib_gid *gid)
+ {
+@@ -1481,15 +1538,13 @@ int nes_ud_subscribe_mcast(struct nes_ud_file *file, union ib_gid *gid)
+ 		  */
+ 			if (pRsc->mcast[i].owner->nes_ud_nic_index !=
+ 						file->nes_ud_nic_index) {
+-				if (get_mcast_number_alloced(pRsc) == 1) {
+-					if ((i == 0) || (i == 1)) {
+-						/* add the mask of other nics
+-						that subscribe this address  */
+-						break;
+-					}
++				if (get_mcast_number_alloced(pRsc) <= 2) {
++					/* add the mask of other nics
++					that subscribe this address  */
++					break;
+ 				}
+ 			}
+-			nes_debug(NES_DBG_UD, "ERROR - subscribing same mcast "
++			printk(KERN_ERR PFX "ERROR - subscribing same mcast "
+ 				"to the diff nes_ud's and NIC  owner_idx = %d "
+ 				"file_idx = %d\n",
+ 				pRsc->mcast[i].owner->nes_ud_nic_index,
+@@ -1499,6 +1554,16 @@ int nes_ud_subscribe_mcast(struct nes_ud_file *file, union ib_gid *gid)
+ 		    goto out;
+ 		}
+ 	}
++	/* check if HW limitation for numebr of subscribed Mgroups per Rsc */
++	/* is exceeded */
++	if (get_subscribed_mcast(pRsc,
++				gid->raw[13],
++				gid->raw[14],
++				gid->raw[15]) >= NES_UD_MAX_MCAST_PER_QP) {
++		printk(KERN_ERR PFX "ERROR - subscribing too much MGroups\n");
++		ret = -EFAULT;
++		goto out;
++	}
+ 
+ 	for (i = 0; i < NES_UD_MCAST_TBL_SZ; i++) {
+ 		if (!pRsc->mcast[i].in_use) {





More information about the ewg mailing list