Author: jfv
Date: Wed Jan 27 20:12:04 2010
New Revision: 203090
URL: http://svn.freebsd.org/changeset/base/203090

Log:
  Add a link tasklet so updates can be sleepable.

Modified:
  head/sys/dev/e1000/if_igb.c
  head/sys/dev/e1000/if_igb.h

Modified: head/sys/dev/e1000/if_igb.c
==============================================================================
--- head/sys/dev/e1000/if_igb.c Wed Jan 27 20:09:20 2010        (r203089)
+++ head/sys/dev/e1000/if_igb.c Wed Jan 27 20:12:04 2010        (r203090)
@@ -244,6 +244,7 @@ static void igb_add_rx_process_limit(str
                    const char *, int *, int);
 static void    igb_handle_rxtx(void *context, int pending);
 static void    igb_handle_que(void *context, int pending);
+static void    igb_handle_link(void *context, int pending);
 
 /* These are MSIX only irq handlers */
 static void    igb_msix_que(void *);
@@ -1203,6 +1204,15 @@ igb_handle_que(void *context, int pendin
        E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims);
 }
 
+/* Deal with link in a sleepable context */
+static void
+igb_handle_link(void *context, int pending)
+{
+       struct adapter *adapter = context;
+
+       adapter->hw.mac.get_link_status = 1;
+       igb_update_link_status(adapter);
+}
 
 /*********************************************************************
  *
@@ -1239,10 +1249,8 @@ igb_irq_fast(void *arg)
        taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
 
        /* Link status change */
-       if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
-               adapter->hw.mac.get_link_status = 1;
-               igb_update_link_status(adapter);
-       }
+       if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))
+               taskqueue_enqueue(adapter->tq, &adapter->link_task);
 
        if (reg_icr & E1000_ICR_RXO)
                adapter->rx_overruns++;
@@ -1352,8 +1360,7 @@ igb_msix_link(void *arg)
        icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
        if (!(icr & E1000_ICR_LSC))
                goto spurious;
-       adapter->hw.mac.get_link_status = 1;
-       igb_update_link_status(adapter);
+       taskqueue_enqueue(adapter->tq, &adapter->link_task);
 
 spurious:
        /* Rearm */
@@ -1986,6 +1993,8 @@ igb_allocate_legacy(struct adapter *adap
         * processing contexts.
         */
        TASK_INIT(&adapter->rxtx_task, 0, igb_handle_rxtx, adapter);
+       /* Make tasklet for deferred link handling */
+       TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter);
        adapter->tq = taskqueue_create_fast("igb_taskq", M_NOWAIT,
            taskqueue_thread_enqueue, &adapter->tq);
        taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq",
@@ -2072,6 +2081,13 @@ igb_allocate_msix(struct adapter *adapte
        }
        adapter->linkvec = vector;
 
+       /* Make tasklet for deferred handling */
+       TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter);
+       adapter->tq = taskqueue_create_fast("igb_link", M_NOWAIT,
+           taskqueue_thread_enqueue, &adapter->tq);
+       taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s link",
+           device_get_nameunit(adapter->dev));
+
        return (0);
 }
 

Modified: head/sys/dev/e1000/if_igb.h
==============================================================================
--- head/sys/dev/e1000/if_igb.h Wed Jan 27 20:09:20 2010        (r203089)
+++ head/sys/dev/e1000/if_igb.h Wed Jan 27 20:12:04 2010        (r203090)
@@ -372,6 +372,7 @@ struct adapter {
 
        int             linkvec;
        int             link_mask;
+       struct task     link_task;
        int             link_irq;
 
        struct ifmedia  media;
@@ -383,7 +384,7 @@ struct adapter {
        struct mtx      core_mtx;
        int             igb_insert_vlan_header;
        struct task     rxtx_task;
-       struct taskqueue *tq;           /* private task queue */
+       struct taskqueue *tq;   /* adapter task queue */
         u16            num_queues;
 
        eventhandler_tag vlan_attach;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to