天天看點

使用 netmap 提升 ixgbe 性能(續)

書接上回  使用 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 隊列收包了。^_^