简介
在网络硬件产品中,需要对网口链路状态(UP/DOWN)进行监测,能够及时感知到链路状态的变更;这里介绍下dpdk中的实现方式,详细信息可以参考示例examples/link_status_interrupt。
示例
使能lsc中断
在rte_eth_dev_configure()端口配置中,对lsc位进行置1。
C
static struct rte_eth_conf port_conf = {
...
.intr_conf = {
.lsc = 1, /**< lsc interrupt feature enabled */
},
};
注册回调函数
注册的事件类型为RTE_ETH_EVENT_INTR_LSC,在链路状态变更的情况下会触发中断,并执行回调函数。
c
rte_eth_dev_callback_register(portid, RTE_ETH_EVENT_INTR_LSC, lsi_event_callback, NULL);
回调函数处理
调用rte_eth_link_get_nowait()获取链路状态信息,并通过rte_eth_link_to_str()转换成字符串。
c
/**
* It will be called as the callback for specified port after a LSI interrupt
* has been fully handled. This callback needs to be implemented carefully as
* it will be called in the interrupt host thread which is different from the
* application main thread.
*
* @param port_id
* Port id.
* @param type
* event type.
* @param param
* Pointer to(address of) the parameters.
*
* @return
* int.
*/
/* lsi_event_callback 8< */
static int
lsi_event_callback(uint16_t port_id, enum rte_eth_event_type type, void *param,
void *ret_param)
{
struct rte_eth_link link;
int ret;
char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
RTE_SET_USED(param);
RTE_SET_USED(ret_param);
printf("\n\nIn registered callback...\n");
printf("Event type: %s\n", type == RTE_ETH_EVENT_INTR_LSC ? "LSC interrupt" : "unknown event");
ret = rte_eth_link_get_nowait(port_id, &link);
if (ret < 0) {
printf("Failed link get on port %d: %s\n",
port_id, rte_strerror(-ret));
return ret;
}
rte_eth_link_to_str(link_status_text, sizeof(link_status_text), &link);
printf("Port %d %s\n\n", port_id, link_status_text);
return 0;
}
/* >8 End of registering one or more callbacks. */