]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mlx4_vnic: Skip fip discover restart if pkey index not changed
authorYuval Shaia <yuval.shaia@oracle.com>
Sun, 1 Feb 2015 00:53:26 +0000 (16:53 -0800)
committerMukesh Kacker <mukesh.kacker@oracle.com>
Wed, 12 Aug 2015 22:53:02 +0000 (15:53 -0700)
Driver receives MAD on any change made to partition table.
This fix aim to cover the case where driver shouldn't restart net interface
when receiving PKEY_CHANGE event but pkey index was not changed.

Ported from UEK3 commit: 7f56a9b2252e732b0d9e2621303b0c2b781bddfc

Orabug: 21446728

Signed-off-by: Yuval Shaia <yuval.shaia@oracle.com>
Reviewed-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx4_vnic/vnic.h
drivers/net/ethernet/mellanox/mlx4_vnic/vnic_fip_discover.c
drivers/net/ethernet/mellanox/mlx4_vnic/vnic_fip_main.c
drivers/net/ethernet/mellanox/mlx4_vnic/vnic_port.c

index afdb7b73c2d4889a61b83dba21eddc82fc3110db..5cf0edf4ef2577e0df2c820448b0ba8c02898897 100644 (file)
@@ -458,6 +458,12 @@ enum {
        MCAST_ATTACH_RUNNING,
 };
 
+/* Flags to pass to port_fip_discover_restart */
+enum {
+       DISCOVER_RESTART_TEST   = 0, /* If needed - restart */
+       DISCOVER_RESTART_FORCE  = 1  /* Force restart */
+};
+
 struct vnic_port_mcast {
        struct rb_node rb_node;
        struct list_head list;
@@ -990,6 +996,7 @@ struct vnic_port {
        struct delayed_work event_task;
        struct delayed_work event_task_light;
        struct delayed_work discover_restart_task;
+       long discover_restart_task_data;
        struct ib_event_handler event_handler;
        struct ib_port_attr attr;
        union ib_gid gid;
index 86f5cc78ce8354025893fcfc9e5c9147be194bb9..df9b3e9781c69a81ff4b2685acd4562350294dbd 100644 (file)
@@ -909,7 +909,7 @@ static int fip_free_gw_done(struct fip_discover *discover, enum fip_flush flush)
        }
 
        list_for_each_entry(curr_gw, &discover->gw_list, list) {
-               if (curr_gw->flush  != FIP_NO_FLUSH) {
+               if (curr_gw->flush != FIP_NO_FLUSH) {
                        up_read(&discover->l_rwsem);
                        return 0;
                }
index 07a6f2ebe54d73dc728a6acfc89a49cc87701298..ac376287dec36ba67f734e4ab201d313eae47bc5 100644 (file)
@@ -69,14 +69,49 @@ void port_fip_discover_restart(struct work_struct *work)
            container_of(work, struct vnic_port, discover_restart_task.work);
        struct fip_discover *discover;
        struct vnic_login *login;
+       u16 new_index;
+       int flush_needed = list_empty(&port->login_list);
 
        vnic_dbg_mark();
        mutex_lock(&port->start_stop_lock);
        vnic_dbg_mark();
        mutex_lock(&port->mlock);
+
+       /* If force restart - skip test */
+       if (port->discover_restart_task_data == DISCOVER_RESTART_FORCE)
+               goto flush;
+
        if (vnic_port_query(port))
                vnic_warn(port->name, "vnic_port_query failed\n");
 
+       vnic_dbg(port->name, "login list is%sempty\n",
+                list_empty(&port->login_list) ? " " : " not ");
+       list_for_each_entry(login, &port->login_list, list) {
+               vnic_dbg(port->name,
+                        "Checking login, dev=%s: pkey=0x%x, pkey_index=0x%x\n",
+                        login->dev->name, login->pkey, login->pkey_index);
+               new_index = 0;
+               if (login->pkey && !ib_find_pkey(port->dev->ca,
+                                                port->num, login->pkey,
+                                                &new_index))
+                       flush_needed = flush_needed ||
+                                      (new_index != login->pkey_index);
+               else
+                       flush_needed = 1;
+               vnic_dbg(port->name, "new_index=0x%x\n", new_index);
+               login->pkey_index = new_index;
+       }
+
+       vnic_info("%s: Flush %sneeded\n", port->name,
+                 flush_needed ? "" : "is not ");
+
+       if (!flush_needed) {
+               mutex_unlock(&port->mlock);
+               goto out;
+       }
+
+flush:
+       vnic_dbg(port->name, "Flushing\n");
        /* bring vnics links down */
        list_for_each_entry(login, &port->login_list, list)
                vnic_mcast_del_all(&login->mcast_tree);
@@ -95,6 +130,9 @@ void port_fip_discover_restart(struct work_struct *work)
                }
        }
 out:
+       /* Reset to default behavior */
+       port->discover_restart_task_data = DISCOVER_RESTART_TEST;
+
        mutex_unlock(&port->start_stop_lock);
        return;
 }
index a973deb7aecdf35f1551e564348f120959a2db1a..b838ff883bce65211cee598c15f597d5c91eb903 100644 (file)
@@ -62,8 +62,9 @@ static void vnic_port_event(struct ib_event_handler *handler,
                /* calls vnic_port_event_task() */
                queue_delayed_work(fip_wq, &port->event_task, msecs_to_jiffies(VNIC_SM_HEADSTART));
                break;
-       case IB_EVENT_PKEY_CHANGE:
        case IB_EVENT_LID_CHANGE:
+               port->discover_restart_task_data = DISCOVER_RESTART_FORCE;
+       case IB_EVENT_PKEY_CHANGE:
                /* calls port_fip_discover_restart() */
                if (no_bxm)
                        queue_delayed_work(fip_wq, &port->event_task, 0);
@@ -227,6 +228,8 @@ struct vnic_port *vnic_port_alloc(struct vnic_ib_dev *vnic_dev, u8 num)
        INIT_DELAYED_WORK(&port->event_task, vnic_port_event_task);
        INIT_DELAYED_WORK(&port->event_task_light, vnic_port_event_task_light);
        INIT_DELAYED_WORK(&port->discover_restart_task, port_fip_discover_restart);
+       /* Set to default behavior */
+       port->discover_restart_task_data = DISCOVER_RESTART_TEST;
        INIT_IB_EVENT_HANDLER(&port->event_handler, vnic_dev->ca,
                              vnic_port_event);
        mutex_init(&port->mlock);