Changeset 1960910 for lib


Ignore:
Timestamp:
01/08/15 18:36:44 (7 years ago)
Author:
Richard Sanger <rsangerarj@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
9b533c6
Parents:
d7fd648
Message:

Add support to detect link status changes in DPDK.
This is useful to ensure the link speed is correct, given that
we generate packet timestamps based on this.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_dpdk.c

    rd7fd648 r1960910  
    911911                },
    912912        },
     913        .intr_conf = {
     914                .lsc = 1
     915        }
    913916};
    914917
     
    966969};
    967970
     971/**
     972 * A callback for a link state change (LSC).
     973 *
     974 * Packets may be received before this notification. In fact the DPDK IGXBE
     975 * driver likes to put a delay upto 5sec before sending this.
     976 *
     977 * We use this to ensure the link speed is correct for our timestamp
     978 * calculations. Because packets might be received before the link up we still
     979 * update this when the packet is received.
     980 *
     981 * @param port The DPDK port
     982 * @param event The TYPE of event (expected to be RTE_ETH_EVENT_INTR_LSC)
     983 * @param cb_arg The dpdk_format_data_t structure associated with the format
     984 */
     985static void dpdk_lsc_callback(uint8_t port, enum rte_eth_event_type event,
     986                              void *cb_arg) {
     987        struct dpdk_format_data_t * format_data = cb_arg;
     988        struct rte_eth_link link_info;
     989        assert(event == RTE_ETH_EVENT_INTR_LSC);
     990        assert(port == format_data->port);
     991
     992        rte_eth_link_get_nowait(port, &link_info);
     993
     994        if (link_info.link_status)
     995                format_data->link_speed = link_info.link_speed;
     996        else
     997                format_data->link_speed = 0;
     998
     999#if DEBUG
     1000        fprintf(stderr, "LSC - link status is %s %s speed=%d\n",
     1001                link_info.link_status ? "up" : "down",
     1002                (link_info.link_duplex == ETH_LINK_FULL_DUPLEX) ?
     1003                                          "full-duplex" : "half-duplex",
     1004                (int) link_info.link_speed);
     1005#endif
     1006
     1007        /* Turns out DPDK drivers might not come back up if the link speed
     1008         * changes. So we reset the autoneg procedure. This is very unsafe
     1009         * we have have threads reading packets and we stop the port. */
     1010#if 0
     1011        if (!link_info.link_status) {
     1012                int ret;
     1013                rte_eth_dev_stop(port);
     1014                ret = rte_eth_dev_start(port);
     1015                if (ret < 0) {
     1016                        fprintf(stderr, "Resetting the DPDK port failed : %s\n",
     1017                                strerror(-ret));
     1018                }
     1019        }
     1020#endif
     1021}
     1022
    9681023/* Attach memory to the port and start the port or restart the port.
    9691024 */
     
    10861141        rte_eth_promiscuous_disable(format_data->port);
    10871142
    1088     /* Wait for the link to come up */
    1089     rte_eth_link_get(format_data->port, &link_info);
     1143        /* Register a callback for link state changes */
     1144        ret = rte_eth_dev_callback_register(format_data->port,
     1145                                            RTE_ETH_EVENT_INTR_LSC,
     1146                                            dpdk_lsc_callback,
     1147                                            format_data);
     1148        /* If this fails it is not a show stopper */
     1149#if DEBUG
     1150        fprintf(stderr, "rte_eth_dev_callback_register failed %d : %s\n",
     1151                ret, strerror(-ret));
     1152#endif
     1153
     1154    /* Get the current link status */
     1155    rte_eth_link_get_nowait(format_data->port, &link_info);
    10901156    format_data->link_speed = link_info.link_speed;
    10911157#if DEBUG
     
    12451311        }*/
    12461312
    1247     /* Wait for the link to come up */
    1248     rte_eth_link_get(format_data->port, &link_info);
     1313    /* Register a callback for link state changes */
     1314    ret = rte_eth_dev_callback_register(format_data->port,
     1315                                        RTE_ETH_EVENT_INTR_LSC,
     1316                                        dpdk_lsc_callback,
     1317                                        format_data);
     1318    /* If this fails it is not a show stopper */
     1319#if DEBUG
     1320    fprintf(stderr, "rte_eth_dev_callback_register failed %d : %s\n",
     1321            ret, strerror(-ret));
     1322#endif
     1323
     1324    /* Get the current link status */
     1325    rte_eth_link_get_nowait(format_data->port, &link_info);
    12491326    format_data->link_speed = link_info.link_speed;
    12501327#if DEBUG
     
    15311608        /* Close the device completely, device cannot be restarted */
    15321609        if (FORMAT(libtrace)->port != 0xFF)
    1533             rte_eth_dev_close(FORMAT(libtrace)->port);
    1534         /* filter here if we used it */
     1610                rte_eth_dev_callback_unregister(FORMAT(libtrace)->port,
     1611                                                RTE_ETH_EVENT_INTR_LSC,
     1612                                                dpdk_lsc_callback,
     1613                                                FORMAT(libtrace));
     1614                rte_eth_dev_close(FORMAT(libtrace)->port);
     1615                /* filter here if we used it */
    15351616                free(libtrace->format_data);
    15361617        }
Note: See TracChangeset for help on using the changeset viewer.