Skip to content

Commit

Permalink
net/iavf: negotiate large VF and request more queues
Browse files Browse the repository at this point in the history
Negotiate large VF capability with PF during VF initialization. If large
VF is supported and the number of queues larger than 16 is required, VF
requests additional queues from PF. Mark the state that large VF is
supported.

If the allocated queues number is larger than 16, the max RSS queue
region cannot be 16 anymore. Add the function to query max RSS queue
region from PF, use it in the RSS initialization and future filters
configuration.

Signed-off-by: Ting Xu <ting.xu@intel.com>
Acked-by: Beilei Xing <beilei.xing@intel.com>
  • Loading branch information
tingxu1 authored and Ferruh Yigit committed Nov 3, 2020
1 parent ef80792 commit e436cd4
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 5 deletions.
7 changes: 6 additions & 1 deletion drivers/net/iavf/iavf.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
#define IAVF_FRAME_SIZE_MAX 9728
#define IAVF_QUEUE_BASE_ADDR_UNIT 128

#define IAVF_MAX_NUM_QUEUES 16
#define IAVF_MAX_NUM_QUEUES_DFLT 16
#define IAVF_MAX_NUM_QUEUES_LV 256

#define IAVF_NUM_MACADDR_MAX 64

Expand Down Expand Up @@ -149,6 +150,7 @@ struct iavf_info {
uint8_t *rss_key;
uint16_t nb_msix; /* number of MSI-X interrupts on Rx */
uint16_t msix_base; /* msix vector base from */
uint16_t max_rss_qregion; /* max RSS queue region supported by PF */
/* queue bitmask for each vector */
uint16_t rxq_map[IAVF_MAX_MSIX_VECTORS];
struct iavf_flow_list flow_list;
Expand All @@ -157,6 +159,8 @@ struct iavf_info {
struct iavf_parser_list dist_parser_list;

struct iavf_fdir_info fdir; /* flow director info */
/* indicate large VF support enabled or not */
bool lv_enabled;
};

#define IAVF_MAX_PKT_TYPE 1024
Expand Down Expand Up @@ -288,4 +292,5 @@ int iavf_add_del_mc_addr_list(struct iavf_adapter *adapter,
struct rte_ether_addr *mc_addrs,
uint32_t mc_addrs_num, bool add);
int iavf_request_queues(struct iavf_adapter *adapter, uint16_t num);
int iavf_get_max_rss_queue_region(struct iavf_adapter *adapter);
#endif /* _IAVF_ETHDEV_H_ */
74 changes: 71 additions & 3 deletions drivers/net/iavf/iavf_ethdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ iavf_init_rss(struct iavf_adapter *adapter)

rss_conf = &adapter->eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
nb_q = RTE_MIN(adapter->eth_dev->data->nb_rx_queues,
IAVF_MAX_NUM_QUEUES);
vf->max_rss_qregion);

if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF)) {
PMD_DRV_LOG(DEBUG, "RSS is not supported");
Expand Down Expand Up @@ -255,13 +255,41 @@ iavf_init_rss(struct iavf_adapter *adapter)
return 0;
}

static int
iavf_queues_req_reset(struct rte_eth_dev *dev, uint16_t num)
{
struct iavf_adapter *ad =
IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
int ret;

ret = iavf_request_queues(ad, num);
if (ret) {
PMD_DRV_LOG(ERR, "request queues from PF failed");
return ret;
}
PMD_DRV_LOG(INFO, "change queue pairs from %u to %u",
vf->vsi_res->num_queue_pairs, num);

ret = iavf_dev_reset(dev);
if (ret) {
PMD_DRV_LOG(ERR, "vf reset failed");
return ret;
}

return 0;
}

static int
iavf_dev_configure(struct rte_eth_dev *dev)
{
struct iavf_adapter *ad =
IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
uint16_t num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
dev->data->nb_tx_queues);
int ret;

ad->rx_bulk_alloc_allowed = true;
/* Initialize to TRUE. If any of Rx queues doesn't meet the
Expand All @@ -273,6 +301,46 @@ iavf_dev_configure(struct rte_eth_dev *dev)
if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH;

/* Large VF setting */
if (num_queue_pairs > IAVF_MAX_NUM_QUEUES_DFLT) {
if (!(vf->vf_res->vf_cap_flags &
VIRTCHNL_VF_LARGE_NUM_QPAIRS)) {
PMD_DRV_LOG(ERR, "large VF is not supported");
return -1;
}

if (num_queue_pairs > IAVF_MAX_NUM_QUEUES_LV) {
PMD_DRV_LOG(ERR, "queue pairs number cannot be larger than %u",
IAVF_MAX_NUM_QUEUES_LV);
return -1;
}

ret = iavf_queues_req_reset(dev, num_queue_pairs);
if (ret)
return ret;

ret = iavf_get_max_rss_queue_region(ad);
if (ret) {
PMD_INIT_LOG(ERR, "get max rss queue region failed");
return ret;
}

vf->lv_enabled = true;
} else {
/* Check if large VF is already enabled. If so, disable and
* release redundant queue resource.
*/
if (vf->lv_enabled) {
ret = iavf_queues_req_reset(dev, num_queue_pairs);
if (ret)
return ret;

vf->lv_enabled = false;
}
/* if large VF is not required, use default rss queue region */
vf->max_rss_qregion = IAVF_MAX_NUM_QUEUES_DFLT;
}

/* Vlan stripping setting */
if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) {
if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
Expand Down Expand Up @@ -586,8 +654,8 @@ iavf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);

dev_info->max_rx_queues = vf->vsi_res->num_queue_pairs;
dev_info->max_tx_queues = vf->vsi_res->num_queue_pairs;
dev_info->max_rx_queues = IAVF_MAX_NUM_QUEUES_LV;
dev_info->max_tx_queues = IAVF_MAX_NUM_QUEUES_LV;
dev_info->min_rx_bufsize = IAVF_BUF_SIZE_MIN;
dev_info->max_rx_pktlen = IAVF_FRAME_SIZE_MAX;
dev_info->max_mtu = dev_info->max_rx_pktlen - IAVF_ETH_OVERHEAD;
Expand Down
31 changes: 30 additions & 1 deletion drivers/net/iavf/iavf_vchnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,8 @@ iavf_get_vf_resource(struct iavf_adapter *adapter)
VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC |
VIRTCHNL_VF_OFFLOAD_FDIR_PF |
VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF |
VIRTCHNL_VF_OFFLOAD_REQ_QUEUES;
VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
VIRTCHNL_VF_LARGE_NUM_QPAIRS;

args.in_args = (uint8_t *)&caps;
args.in_args_size = sizeof(caps);
Expand Down Expand Up @@ -1267,3 +1268,31 @@ iavf_request_queues(struct iavf_adapter *adapter, uint16_t num)

return -1;
}

int
iavf_get_max_rss_queue_region(struct iavf_adapter *adapter)
{
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
struct iavf_cmd_info args;
uint16_t qregion_width;
int err;

args.ops = VIRTCHNL_OP_GET_MAX_RSS_QREGION;
args.in_args = NULL;
args.in_args_size = 0;
args.out_buffer = vf->aq_resp;
args.out_size = IAVF_AQ_BUF_SZ;

err = iavf_execute_vf_cmd(adapter, &args);
if (err) {
PMD_DRV_LOG(ERR, "Failed to execute command of VIRTCHNL_OP_GET_MAX_RSS_QREGION");
return err;
}

qregion_width =
((struct virtchnl_max_rss_qregion *)args.out_buffer)->qregion_width;

vf->max_rss_qregion = (uint16_t)(1 << qregion_width);

return 0;
}

0 comments on commit e436cd4

Please sign in to comment.