> -----Original Message----- > From: Chen, Jing D > Sent: Tuesday, December 16, 2014 10:29 AM > To: Zhang, Helin; dev at dpdk.org > Cc: Rowden, Aaron F > Subject: RE: [dpdk-dev] [PATCH v2] i40e: workaround for X710 performance > issues > > Hi Helin, > > > -----Original Message----- > > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Helin Zhang > > Sent: Monday, December 15, 2014 3:56 PM > > To: dev at dpdk.org > > Cc: Rowden, Aaron F > > Subject: [dpdk-dev] [PATCH v2] i40e: workaround for X710 performance > > issues > > > > As the fixes of below performance issues on X710 may not be integrated > > in latest version of firmware, a workaround in software PMD is needed. > > It is to re-configure 3 specific registers after being initialized. > > - Cannot achieve line rate on X710. > > packet size? For 10G, it is expected to achieve line rate for all packet sizes.
> > > - Performance reduction when promiscuous mode is disabled. > > You'd better add above descriptions in line with the code. It is to re-configure 3 specific registers which is not open in datasheet. So no need to describe the name and the functionality of those registers in detail. > > > Note that this workaround can be removed if the fixes are integrated > > in the firmware in future. > > > > I saw below code applied register setting in case it's 40G device. Can you > give > more description on what device this patch would boost performance? > Will 10G fiber interface benefit from the change? It is for X710 only. For XL710, debugging is still in process. > > > Signed-off-by: Helin Zhang <helin.zhang at intel.com> > > --- > > lib/librte_pmd_i40e/i40e_ethdev.c | 87 > > +++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 87 insertions(+) > > > > v2 changes: > > * Added a compile error fix. > > > > diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c > > b/lib/librte_pmd_i40e/i40e_ethdev.c > > index 008d62c..82c072b 100644 > > --- a/lib/librte_pmd_i40e/i40e_ethdev.c > > +++ b/lib/librte_pmd_i40e/i40e_ethdev.c > > @@ -198,6 +198,7 @@ static int i40e_dev_filter_ctrl(struct rte_eth_dev > *dev, > > enum rte_filter_type filter_type, > > enum rte_filter_op filter_op, > > void *arg); > > +static void i40e_configure_registers(struct i40e_hw *hw); > > > > /* Default hash key buffer for RSS */ static uint32_t > > rss_key_default[I40E_PFQF_HKEY_MAX_INDEX + 1]; @@ -443,6 +444,15 > @@ > > eth_i40e_dev_init(__rte_unused struct eth_driver *eth_drv, > > /* Clear PXE mode */ > > i40e_clear_pxe_mode(hw); > > > > + /* > > + * On X710, as old version of firmwares may have performance issues, > > + * 3 registers need to be re-configured with new values. And the > > latest > > + * version of firmware may not contain the fixes, workaround in SW > > + * driver is needed. This workaround can be removed when the fixes > > are > > + * integrated in firmware in future. > > + */ > > + i40e_configure_registers(hw); > > + > > /* Get hw capabilities */ > > ret = i40e_get_cap(hw); > > if (ret != I40E_SUCCESS) { > > @@ -5294,3 +5304,80 @@ i40e_pctype_to_flowtype(enum > i40e_filter_pctype > > pctype) > > > > return flowtype_table[pctype]; > > } > > + > > +static int > > +i40e_debug_read_register(struct i40e_hw *hw, uint32_t addr, uint64_t > > *val) > > +{ > > + struct i40e_aq_desc desc; > > + struct i40e_aqc_debug_reg_read_write *cmd = > > + (struct i40e_aqc_debug_reg_read_write > > *)&desc.params.raw; > > + enum i40e_status_code status; > > + > > + i40e_fill_default_direct_cmd_desc(&desc, > > i40e_aqc_opc_debug_read_reg); > > + cmd->address = rte_cpu_to_le_32(addr); > > + status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL); > > + if (status < 0) > > + return status; > > + > > + *val = ((uint64_t)(rte_le_to_cpu_32(cmd->value_high)) << > > (CHAR_BIT * > > + sizeof(uint32_t))) + rte_le_to_cpu_32(cmd- > > >value_low); > > + > > + return status; > > +} > > + > > +/* > > + * On X710, as old version of firmwares may have performance issues, > > + * 3 registers need to be re-configured with new values. And the > > +latest > > version > > + * of firmware may not contain the fixes, workaround in SW driver is > > needed. > > + * This workaround can be removed when the fixes are integrated in > > firmware in > > + * future. > > + */ > > +static void > > +i40e_configure_registers(struct i40e_hw *hw) { > > +#define I40E_GL_SWR_PRI_JOIN_MAP_0 0x26CE00 > > +#define I40E_GL_SWR_PRI_JOIN_MAP_2 0x26CE08 > > +#define I40E_GL_SWR_PM_UP_THR 0x269FBC > > +#define I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE 0x10000200 #define > > +I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE 0x011f0200 > > +#define I40E_GL_SWR_PM_UP_THR_VALUE 0x03030303 > > + > > + static const struct { > > + uint32_t addr; > > + uint64_t val; > > + } reg_table[] = { > > + {I40E_GL_SWR_PRI_JOIN_MAP_0, > > I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE}, > > + {I40E_GL_SWR_PRI_JOIN_MAP_2, > > I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE}, > > + {I40E_GL_SWR_PM_UP_THR, > > I40E_GL_SWR_PM_UP_THR_VALUE}, > > + }; > > + uint64_t reg; > > + uint32_t i; > > + int ret; > > + > > + /* Below fix is for X710 only */ > > + if (i40e_is_40G_device(hw->device_id)) > > + return; > > + > > + for (i = 0; i < RTE_DIM(reg_table); i++) { > > + ret = i40e_debug_read_register(hw, reg_table[i].addr, ®); > > + if (ret < 0) { > > + PMD_DRV_LOG(ERR, "Failed to read from 0x%x\n", > > + reg_table[i].addr); > > + break; > > + } > > + PMD_DRV_LOG(DEBUG, "Read from 0x%x: 0x%lx", > > reg_table[i].addr, > > + reg); > > PRIu64? Yes, it would be better to use PRIu64. > > > + if (reg == reg_table[i].val) > > + continue; > > + > > + ret = i40e_aq_debug_write_register(hw, reg_table[i].addr, > > + reg_table[i].val, NULL); > > + if (ret < 0) { > > + PMD_DRV_LOG(ERR, "Failed to write 0x%lx to > > 0x%x\n", > > + reg_table[i].val, reg_table[i].addr); > > PRIu64? > > > + break; > > + } > > + PMD_DRV_LOG(DEBUG, "Write to 0x%x: 0x%lx", > > reg_table[i].addr, > > + reg_table[i].val); > > PRIu64? > > > + } > > +} > > I saw some wrong code alignment above, but not sure how it looks like on > terminal, please double check. All passed checks by checkpatch.pl. Email always shows different format than patch itself. > > > -- > > 1.8.1.4