書接上回 使用 netmap 提升 ixgbe 性能
上次打算通過 get_channels( )方法來擷取隊列的個數,不過我使用的核心的版本中,ethtool_ops 下并沒有 get_channels( ) 方法。。。
那腫麼辦,如何擷取網卡隊列?
上次強制改過 RX 的個數為網卡中 RX 的個數,可惜行不通,還是找其他方法吧。
翻了翻我使用核心版本的源碼,發現有 get_channels( ) 方法,不過并不在 ethtool_ops 中,而是作為擴充在struct ethtool_ops_ext 中:
struct ethtool_ops_ext {
size_t size;
u32 (*get_rxfh_indir_size)(struct net_device *);
int (*get_rxfh_indir)(struct net_device *, u32 *);
int (*set_rxfh_indir)(struct net_device *, const u32 *);
void (*get_channels)(struct net_device *, struct ethtool_channels *); // 在這裡
int (*set_channels)(struct net_device *, struct ethtool_channels *);
int (*get_dump_flag)(struct net_device *, struct ethtool_dump *);
int (*get_dump_data)(struct net_device *, struct ethtool_dump *, void *);
int (*set_dump)(struct net_device *, struct ethtool_dump *);
int (*get_module_info)(struct net_device *, struct ethtool_modinfo *);
int (*get_module_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *);
int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state);
int (*reset)(struct net_device *, u32 *);
int (*get_eee)(struct net_device *, struct ethtool_eee *);
int (*set_eee)(struct net_device *, struct ethtool_eee *);
int (*get_ts_info)(struct net_device *, struct ethtool_ts_info *);
};
ixgbe 是這麼設定的:
static const struct ethtool_ops_ext ixgbe_ethtool_ops_ext = {
.size = sizeof(struct ethtool_ops_ext),
.get_channels = ixgbe_get_channels,
.set_channels = ixgbe_set_channels,
.get_ts_info = ixgbe_get_ts_info,
.get_module_info = ixgbe_get_module_info,
.get_module_eeprom = ixgbe_get_module_eeprom,
};
void ixgbe_set_ethtool_ops(struct net_device *netdev)
{
SET_ETHTOOL_OPS(netdev, &ixgbe_ethtool_ops); // ixgbe_ethtool_ops 是 ethtool_ops
set_ethtool_ops_ext(netdev, &ixgbe_ethtool_ops_ext); // ixgbe_ethtool_ops_ext 裡面有我們要的 get_channels
}
那好,我們改動 netmap 關于通過 net_device 設定網卡收發隊列的部分,加入 struct ethtool_ops_ext 的支援:
void nm_os_generic_find_num_queues(struct ifnet *ifp, u_int *txq, u_int *rxq)
{
#ifdef NETMAP_LINUX_HAVE_SET_CHANNELS
struct ethtool_channels ch;
memset(&ch, 0, sizeof(ch));
if ((ifp->ethtool_ops && ifp->ethtool_ops->get_channels) ||
(get_ethtool_ops_ext(ifp) && get_ethtool_ops_ext(ifp)->get_channels)) { // 這裡添加 get_ethtool_ops_ext
if (ifp->ethtool_ops->get_channels) {
ifp->ethtool_ops->get_channels(ifp, &ch);
} else if (get_ethtool_ops_ext(ifp)->get_channels) { // 分支判斷是否支援 ethtool_opt 的擴充
get_ethtool_ops_ext(ifp)->get_channels(ifp, &ch);
}
*txq = ch.tx_count ? ch.tx_count : ch.combined_count;
*rxq = ch.rx_count ? ch.rx_count : ch.combined_count;
} else
#endif /* HAVE_SET_CHANNELS */
{
*txq = ifp->real_num_tx_queues;
#if defined(NETMAP_LINUX_HAVE_REAL_NUM_RX_QUEUES)
*rxq = ifp->real_num_rx_queues;
#else
*rxq = 1;
#endif /* HAVE_REAL_NUM_RX_QUEUES */
}
}
重新編譯源碼,加載子產品運作,嗯嗯,可以設定 RX 為 8 隊列了,這回可以使用 8 隊列收包了。^_^