[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