Author: np
Date: Tue May 19 16:28:20 2020
New Revision: 361261
URL: https://svnweb.freebsd.org/changeset/base/361261

Log:
  cxgbe/iw_cxgbe: Add an async callback to notify iw_cxgbe in case of a
  fatal error.
  
  Submitted by: Krishnamraju Eraparaju @ Chelsio
  MFC after:    2 weeks
  Sponsored by: Chelsio Communications

Modified:
  head/sys/dev/cxgbe/adapter.h
  head/sys/dev/cxgbe/iw_cxgbe/cm.c
  head/sys/dev/cxgbe/iw_cxgbe/device.c
  head/sys/dev/cxgbe/offload.h
  head/sys/dev/cxgbe/t4_main.c

Modified: head/sys/dev/cxgbe/adapter.h
==============================================================================
--- head/sys/dev/cxgbe/adapter.h        Tue May 19 16:06:03 2020        
(r361260)
+++ head/sys/dev/cxgbe/adapter.h        Tue May 19 16:28:20 2020        
(r361261)
@@ -830,6 +830,7 @@ struct adapter {
        int sc_do_rxcopy;
 
        struct taskqueue *tq[MAX_NCHAN];        /* General purpose taskqueues */
+       struct task async_event_task;
        struct port_info *port[MAX_NPORTS];
        uint8_t chan_map[MAX_NCHAN];            /* channel -> port */
 

Modified: head/sys/dev/cxgbe/iw_cxgbe/cm.c
==============================================================================
--- head/sys/dev/cxgbe/iw_cxgbe/cm.c    Tue May 19 16:06:03 2020        
(r361260)
+++ head/sys/dev/cxgbe/iw_cxgbe/cm.c    Tue May 19 16:28:20 2020        
(r361261)
@@ -1085,7 +1085,7 @@ c4iw_so_upcall(struct socket *so, void *arg, int waitf
         * Wake up any threads waiting in rdma_init()/rdma_fini(),
         * with locks held.
         */
-       if (so->so_error)
+       if (so->so_error || (ep->com.dev->rdev.flags & T4_FATAL_ERROR))
                c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
        add_ep_to_req_list(ep, C4IW_EVENT_SOCKET);
 
@@ -2700,6 +2700,11 @@ c4iw_create_listen(struct iw_cm_id *cm_id, int backlog
 
        CTR3(KTR_IW_CXGBE, "%s: cm_id %p, backlog %s", __func__, cm_id,
                        backlog);
+       if (c4iw_fatal_error(&dev->rdev)) {
+               CTR2(KTR_IW_CXGBE, "%s: cm_id %p, fatal error", __func__,
+                              cm_id);
+               return -EIO;
+       }
        lep = alloc_ep(sizeof(*lep), GFP_KERNEL);
        lep->com.cm_id = cm_id;
        ref_cm_id(&lep->com);
@@ -2800,7 +2805,6 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt,
 {
        int ret = 0;
        int close = 0;
-       int fatal = 0;
        struct c4iw_rdev *rdev;
 
 
@@ -2809,12 +2813,14 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt,
        rdev = &ep->com.dev->rdev;
 
        if (c4iw_fatal_error(rdev)) {
-
-               CTR2(KTR_IW_CXGBE, "%s:ced1 %p", __func__, ep);
-               fatal = 1;
+               CTR3(KTR_IW_CXGBE, "%s:ced1 fatal error %p %s", __func__, ep,
+                                       states[ep->com.state]);
+               if (ep->com.state != DEAD) {
+                       send_abort(ep);
+                       ep->com.state = DEAD;
+               }
                close_complete_upcall(ep, -ECONNRESET);
-               send_abort(ep);
-               ep->com.state = DEAD;
+               return ECONNRESET;
        }
        CTR3(KTR_IW_CXGBE, "%s:ced2 %p %s", __func__, ep,
            states[ep->com.state]);
@@ -2877,9 +2883,7 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt,
                        CTR2(KTR_IW_CXGBE, "%s:ced4 %p", __func__, ep);
                        set_bit(EP_DISC_ABORT, &ep->com.history);
                        close_complete_upcall(ep, -ECONNRESET);
-                       ret = send_abort(ep);
-                       if (ret)
-                               fatal = 1;
+                       send_abort(ep);
                } else {
 
                        CTR2(KTR_IW_CXGBE, "%s:ced5 %p", __func__, ep);
@@ -2889,33 +2893,28 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt,
                                ep->com.state = MORIBUND;
 
                        CURVNET_SET(ep->com.so->so_vnet);
-                       sodisconnect(ep->com.so);
+                       ret = sodisconnect(ep->com.so);
                        CURVNET_RESTORE();
-               }
-
-       }
-
-       if (fatal) {
-               set_bit(EP_DISC_FAIL, &ep->com.history);
-               if (!abrupt) {
-                       STOP_EP_TIMER(ep);
-                       close_complete_upcall(ep, -EIO);
-               }
-               if (ep->com.qp) {
-                       struct c4iw_qp_attributes attrs = {0};
-
-                       attrs.next_state = C4IW_QP_STATE_ERROR;
-                       ret = c4iw_modify_qp(ep->com.dev, ep->com.qp,
-                                               C4IW_QP_ATTR_NEXT_STATE,
-                                               &attrs, 1);
                        if (ret) {
-                               CTR2(KTR_IW_CXGBE, "%s:ced7 %p", __func__, ep);
-                               printf("%s - qp <- error failed!\n", __func__);
+                               CTR2(KTR_IW_CXGBE, "%s:ced6 %p", __func__, ep);
+                               STOP_EP_TIMER(ep);
+                               send_abort(ep);
+                               ep->com.state = DEAD;
+                               close_complete_upcall(ep, -ECONNRESET);
+                               set_bit(EP_DISC_FAIL, &ep->com.history);
+                               if (ep->com.qp) {
+                                       struct c4iw_qp_attributes attrs = {0};
+
+                                       attrs.next_state = C4IW_QP_STATE_ERROR;
+                                       ret = c4iw_modify_qp(
+                                                       ep->com.dev, ep->com.qp,
+                                                       C4IW_QP_ATTR_NEXT_STATE,
+                                                       &attrs, 1);
+                                       CTR3(KTR_IW_CXGBE, "%s:ced7 %p ret %d",
+                                               __func__, ep, ret);
+                               }
                        }
                }
-               release_ep_resources(ep);
-               ep->com.state = DEAD;
-               CTR2(KTR_IW_CXGBE, "%s:ced6 %p", __func__, ep);
        }
        c4iw_put_ep(&ep->com);
        CTR2(KTR_IW_CXGBE, "%s:cedE %p", __func__, ep);

Modified: head/sys/dev/cxgbe/iw_cxgbe/device.c
==============================================================================
--- head/sys/dev/cxgbe/iw_cxgbe/device.c        Tue May 19 16:06:03 2020        
(r361260)
+++ head/sys/dev/cxgbe/iw_cxgbe/device.c        Tue May 19 16:28:20 2020        
(r361261)
@@ -261,11 +261,13 @@ static int c4iw_mod_load(void);
 static int c4iw_mod_unload(void);
 static int c4iw_activate(struct adapter *);
 static int c4iw_deactivate(struct adapter *);
+static void c4iw_async_event(struct adapter *);
 
 static struct uld_info c4iw_uld_info = {
        .uld_id = ULD_IWARP,
        .activate = c4iw_activate,
        .deactivate = c4iw_deactivate,
+       .async_event = c4iw_async_event,
 };
 
 static int
@@ -324,6 +326,23 @@ c4iw_deactivate(struct adapter *sc)
        sc->iwarp_softc = NULL;
 
        return (0);
+}
+
+static void
+c4iw_async_event(struct adapter *sc)
+{
+       struct c4iw_dev *iwsc = sc->iwarp_softc;
+
+       if (iwsc) {
+               struct ib_event event = {0};
+
+               device_printf(sc->dev,
+                             "iWARP driver received FATAL ERROR event.\n");
+               iwsc->rdev.flags |= T4_FATAL_ERROR;
+               event.event  = IB_EVENT_DEVICE_FATAL;
+               event.device = &iwsc->ibdev;
+               ib_dispatch_event(&event);
+       }
 }
 
 static void

Modified: head/sys/dev/cxgbe/offload.h
==============================================================================
--- head/sys/dev/cxgbe/offload.h        Tue May 19 16:06:03 2020        
(r361260)
+++ head/sys/dev/cxgbe/offload.h        Tue May 19 16:28:20 2020        
(r361261)
@@ -228,6 +228,7 @@ struct uld_info {
        int uld_id;
        int (*activate)(struct adapter *);
        int (*deactivate)(struct adapter *);
+       void (*async_event)(struct adapter *);
 };
 
 struct tom_tunables {

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c        Tue May 19 16:06:03 2020        
(r361260)
+++ head/sys/dev/cxgbe/t4_main.c        Tue May 19 16:28:20 2020        
(r361261)
@@ -758,6 +758,7 @@ static int read_i2c(struct adapter *, struct t4_i2c_da
 static int clear_stats(struct adapter *, u_int);
 #ifdef TCP_OFFLOAD
 static int toe_capability(struct vi_info *, int);
+static void t4_async_event(void *, int);
 #endif
 static int mod_event(module_t, int, void *);
 static int notify_siblings(device_t, int);
@@ -1063,6 +1064,10 @@ t4_attach(device_t dev)
 
        callout_init(&sc->ktls_tick, 1);
 
+#ifdef TCP_OFFLOAD
+       TASK_INIT(&sc->async_event_task, 0, t4_async_event, sc);
+#endif
+
        rc = t4_map_bars_0_and_4(sc);
        if (rc != 0)
                goto done; /* error message displayed already */
@@ -1567,6 +1572,10 @@ t4_detach_common(device_t dev)
                }
        }
 
+#ifdef TCP_OFFLOAD
+       taskqueue_drain(taskqueue_thread, &sc->async_event_task);
+#endif
+
        for (i = 0; i < sc->intr_count; i++)
                t4_free_irq(sc, &sc->irq[i]);
 
@@ -2788,6 +2797,9 @@ t4_fatal_err(struct adapter *sc, bool fw_error)
                sc->flags |= ADAP_ERR;
                ADAPTER_UNLOCK(sc);
        }
+#ifdef TCP_OFFLOAD
+       taskqueue_enqueue(taskqueue_thread, &sc->async_event_task);
+#endif
 
        if (t4_panic_on_fatal_err) {
                log(LOG_ALERT, "%s: panic on fatal error after 30s",
@@ -10857,6 +10869,25 @@ t4_deactivate_uld(struct adapter *sc, int id)
        sx_sunlock(&t4_uld_list_lock);
 
        return (rc);
+}
+
+static void
+t4_async_event(void *arg, int n)
+{
+       struct uld_info *ui;
+       struct adapter *sc = (struct adapter *)arg;
+
+       if (begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4async") != 0)
+               return;
+       sx_slock(&t4_uld_list_lock);
+       SLIST_FOREACH(ui, &t4_uld_list, link) {
+               if (ui->uld_id == ULD_IWARP) {
+                       ui->async_event(sc);
+                       break;
+               }
+       }
+       sx_sunlock(&t4_uld_list_lock);
+       end_synchronized_op(sc, 0);
 }
 
 int
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to