i40e: Fix VF's link state notification
Subsystems (2)
PATCH 1/12 i40e: Fix VF's link state notification
From: Mariusz Stachura <[email protected]>
This patch moves saving old link status information after the call to i40e_get_link_status(). Mentioned function updates both old and the new link info, so reading it before results in not notifying VF about the PF link state change.
--- drivers/net/ethernet/intel/i40e/i40e_main.c | 5 ----- 1 file changed, 5 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_main.c +0 -5
@@ -8446,14 +8446,9 @@ static void i40e_link_event(struct i40e_pf *pf)i40e_status status;bool new_link, old_link; -/* save off old link status information */ - pf->hw.phy.link_info_old = pf->hw.phy.link_info; -/* set this to force the get_link_status call to refresh state */ pf->hw.phy.get_link_info = true; - old_link = (pf->hw.phy.link_info_old.link_info &I40E_AQ_LINK_UP ); - status =i40e_get_link_status (&pf->hw, &new_link);/* On success, disable temp link polling */
Signature · 1 line
2.9.5
PATCH 2/12 i40e: convert queue stats to i40e_stats array
From: Jacob Keller <[email protected]>
Use an i40e_stats array to handle the queue stats, instead of coding similar functionality separately. Because of how the queue stats are accessed on some kernels, we can't easily use i40e_add_ethtool_stats.
Instead, implement a separate helper, i40e_add_queue_stats, which we'll use instead. This helper will correctly implement the u64_stats_fetch_begin_irq logic and allow retries until successful. We share the most complex code by re-using i40e_add_one_ethtool_stat.
This logic additionally easily supports skipping disabled rings by using a ternary operator before calling the u64_stats_fetch_begin_irq() function, so that we correctly zero-out the stats values without having to perform two separate sections of code.
This significantly reduces the boiler plate code in i40e_get_ethtool_stats, and helps keep the complex logic contained to as few functions as possible.
With this patch, we've finally converted all the statistics to use the helpers and the i40e_stats function.
--- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 148 +++++++++++++++---------- 1 file changed, 89 insertions(+), 59 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_ethtool.c +89 -59
@@ -33,6 +33,8 @@ struct i40e_stats { I40E_STAT(struct i40e_veb, _name, _stat)#define I40E_PFC_STAT (_name, _stat) \ I40E_STAT(struct i40e_pfc_stats, _name, _stat) +#define I40E_QUEUE_STAT (_name, _stat) \ + I40E_STAT(struct i40e_ring, _name, _stat)static const struct i40e_stats i40e_gstrings_net_stats[] = {I40E_NETDEV_STAT (rx_packets),
@@ -171,20 +173,16 @@ static const struct i40e_stats i40e_gstrings_pfc_stats[] = { I40E_PFC_STAT("port.rx_priority_%u_xon_2_xoff", priority_xon_2_xoff), }; -/* We use num_tx_queues here as a proxy for the maximum number of queues -* available because we always allocate queues symmetrically. -*/ -#define I40E_MAX_NUM_QUEUES (n) ((n)->num_tx_queues) -#define I40E_QUEUE_STATS_LEN (n) \ - (I40E_MAX_NUM_QUEUES(n) \ - * 2/* Tx and Rx together */ \ - * (sizeof(struct i40e_queue_stats) / sizeof(u64))) -#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats) +static const struct i40e_stats i40e_gstrings_queue_stats[] = { +I40E_QUEUE_STAT ("%s-%u.packets" , stats.packets), +I40E_QUEUE_STAT ("%s-%u.bytes" , stats.bytes), +}; +#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats) +#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats) -#define I40E_VSI_STATS_LEN (n) (I40E_NETDEV_STATS_LEN + \ - I40E_MISC_STATS_LEN + \ - I40E_QUEUE_STATS_LEN((n))) + +#define I40E_VSI_STATS_LEN (I40E_NETDEV_STATS_LEN + I40E_MISC_STATS_LEN)#define I40E_PFC_STATS_LEN (ARRAY_SIZE(i40e_gstrings_pfc_stats) * \ I40E_MAX_USER_PRIORITY)
@@ -193,10 +191,15 @@ static const struct i40e_stats i40e_gstrings_pfc_stats[] = { (ARRAY_SIZE(i40e_gstrings_veb_tc_stats) * \ I40E_MAX_TRAFFIC_CLASS)) -#define I40E_PF_STATS_LEN (n) (I40E_GLOBAL_STATS_LEN + \ +#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats) + +#define I40E_PF_STATS_LEN (I40E_GLOBAL_STATS_LEN + \ I40E_PFC_STATS_LEN + \ I40E_VEB_STATS_LEN + \ - I40E_VSI_STATS_LEN((n))) + I40E_VSI_STATS_LEN) + +/* Length of stats for a single queue */ +#define I40E_QUEUE_STATS_LEN ARRAY_SIZE(i40e_gstrings_queue_stats)enum i40e_ethtool_test_id {I40E_ETH_TEST_REG =0 ,
@@ -1701,11 +1704,30 @@ static int i40e_get_stats_count(struct net_device *netdev)struct i40e_netdev_priv *np =netdev_priv (netdev);struct i40e_vsi *vsi = np->vsi;struct i40e_pf *pf = vsi->back; +int stats_len;if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id ==1 ) -return I40E_PF_STATS_LEN (netdev); + stats_len =I40E_PF_STATS_LEN ;else -return I40E_VSI_STATS_LEN (netdev); + stats_len =I40E_VSI_STATS_LEN ; + +/* The number of stats reported for a given net_device must remain +* constant throughout the life of that device. +* +* This is because the API for obtaining the size, strings, and stats +* is spread out over three separate ethtool ioctls. There is no safe +* way to lock the number of stats across these calls, so we must +* assume that they will never change. +* +* Due to this, we report the maximum number of queues, even if not +* every queue is currently configured. Since we always allocate +* queues in pairs, we'll just use netdev->num_tx_queues * 2. This +* works because the num_tx_queues is set at device creation and never +* changes. +*/ + stats_len +=I40E_QUEUE_STATS_LEN *2 * netdev->num_tx_queues; + +return stats_len; }static int i40e_get_sset_count (struct net_device *netdev,int sset)
@@ -1734,8 +1756,8 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset)* @stat: the stat definition * * Copies the stat data defined by the pointer and stat structure pair into -* the memory supplied as data. Used to implement i40e_add_ethtool_stats. -* If the pointer is null, data will be zero'd. +* the memory supplied as data. Used to implement i40e_add_ethtool_stats and +* i40e_add_queue_stats. If the pointer is null, data will be zero'd. */ static inline void i40e_add_one_ethtool_stat(u64 *data, void *pointer,
@@ -1811,6 +1833,45 @@ __i40e_add_ethtool_stats(u64 **data, void *pointer,__i40e_add_ethtool_stats (data, pointer, stats,ARRAY_SIZE (stats))/** +* i40e_add_queue_stats - copy queue statistics into supplied buffer +* @data: ethtool stats buffer +* @ring: the ring to copy +* +* Queue statistics must be copied while protected by +* u64_stats_fetch_begin_irq, so we can't directly use i40e_add_ethtool_stats. +* Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the +* ring pointer is null, zero out the queue stat values and update the data +* pointer. Otherwise safely copy the stats from the ring into the supplied +* buffer and update the data pointer when finished. +* +* This function expects to be called while under rcu_read_lock(). + **/ +static inline void +i40e_add_queue_stats (u64 **data,struct i40e_ring *ring) +{ +const unsigned int size =ARRAY_SIZE (i40e_gstrings_queue_stats); +const struct i40e_stats *stats = i40e_gstrings_queue_stats; +unsigned int start; +unsigned int i; + +/* To avoid invalid statistics values, ensure that we keep retrying +* the copy until we get a consistent value according to +* u64_stats_fetch_retry_irq. But first, make sure our ring is +* non-null before attempting to access its syncp. +*/ +do { + start = !ring ?0 :u64_stats_fetch_begin_irq (&ring->syncp); +for (i =0 ; i < size; i++) { +i40e_add_one_ethtool_stat (&(*data)[i], ring, + &stats[i]); + } + }while (ring &&u64_stats_fetch_retry_irq (&ring->syncp, start)); + +/* Once we successfully copy the stats in, update the data pointer */ + data += size; +} + +/** * i40e_get_pfc_stats - copy HW PFC statistics to formatted structure * @pf: the PF device structure * @i: the priority value to copy
@@ -1853,12 +1914,10 @@ static void i40e_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, u64 *data) { struct i40e_netdev_priv *np = netdev_priv(netdev); -struct i40e_ring *tx_ring, *rx_ring;struct i40e_vsi *vsi = np->vsi;struct i40e_pf *pf = vsi->back;struct i40e_veb *veb = pf->veb[pf->lan_veb];unsigned int i; -unsigned int start;bool veb_stats;u64 *p = data;
@@ -1870,38 +1929,12 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,i40e_add_ethtool_stats (&data, vsi, i40e_gstrings_misc_stats);rcu_read_lock (); -for (i =0 ; i <I40E_MAX_NUM_QUEUES (netdev) ; i++) { - tx_ring =READ_ONCE (vsi->tx_rings[i]); - -if (!tx_ring) { -/* Bump the stat counter to skip these stats, and make -* sure the memory is zero'd -*/ - *(data++) =0 ; - *(data++) =0 ; - *(data++) =0 ; - *(data++) =0 ; -continue ; - } - -/* process Tx ring statistics */ -do { - start =u64_stats_fetch_begin_irq (&tx_ring->syncp); - data[0 ] = tx_ring->stats.packets; - data[1 ] = tx_ring->stats.bytes; - }while (u64_stats_fetch_retry_irq (&tx_ring->syncp, start)); - data +=2 ; - -/* Rx ring is the 2nd half of the queue pair */ - rx_ring = &tx_ring[1 ]; -do { - start =u64_stats_fetch_begin_irq (&rx_ring->syncp); - data[0 ] = rx_ring->stats.packets; - data[1 ] = rx_ring->stats.bytes; - }while (u64_stats_fetch_retry_irq (&rx_ring->syncp, start)); - data +=2 ; +for (i =0 ; i < netdev->num_tx_queues; i++) { +i40e_add_queue_stats (&data,READ_ONCE (vsi->tx_rings[i])); +i40e_add_queue_stats (&data,READ_ONCE (vsi->rx_rings[i])); }rcu_read_unlock (); +if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id !=1 ) goto check_data_pointer;
@@ -1990,16 +2023,13 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)i40e_add_stat_strings (&data, i40e_gstrings_misc_stats); -for (i =0 ; i <I40E_MAX_NUM_QUEUES (netdev); i++) { -snprintf (data,ETH_GSTRING_LEN ,"tx-%u.tx_packets" , i); - data +=ETH_GSTRING_LEN ; -snprintf (data,ETH_GSTRING_LEN ,"tx-%u.tx_bytes" , i); - data +=ETH_GSTRING_LEN ; -snprintf (data,ETH_GSTRING_LEN ,"rx-%u.rx_packets" , i); - data +=ETH_GSTRING_LEN ; -snprintf (data,ETH_GSTRING_LEN ,"rx-%u.rx_bytes" , i); - data +=ETH_GSTRING_LEN ; +for (i =0 ; i < netdev->num_tx_queues; i++) { +i40e_add_stat_strings (&data, i40e_gstrings_queue_stats, +"tx" , i); +i40e_add_stat_strings (&data, i40e_gstrings_queue_stats, +"rx" , i); } +if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id !=1 )return ;
Signature · 1 line
2.9.5
Bowers
PATCH 2/12 i40e: convert queue stats to i40e_stats array
Quoted 28 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:12 AM
To: Michael, Alice <[email protected]>; intel-wired-
lan at lists.osuosl.org
Subject: [Intel-wired-lan] [next PATCH S95 02/12] i40e: convert queue stats toi40e_statsarrayFrom: Jacob Keller <[email protected]>
Use an
i40e_statsarray to handle the queue stats, instead of coding similar functionality separately. Because of how the queue stats are accessed on some kernels, we can't easily usei40e_add_ethtool_stats.Instead, implement a separate helper,
i40e_add_queue_stats, which we'll use instead. This helper will correctly implement theu64_stats_fetch_begin_irqlogic and allow retries until successful. We share the most complex code by re-usingi40e_add_one_ethtool_stat.This logic additionally easily supports skipping disabled rings by using a ternary operator before calling the
u64_stats_fetch_begin_irq()function, so that we correctly zero-out the stats values without having to perform two separate sections of code.This significantly reduces the boiler plate code in
i40e_get_ethtool_stats, and helps keep the complex logic contained to as few functions as possible.
Quoted 8 lines
With this patch, we've finally converted all the statistics to use the helpers and the
i40e_statsfunction.Signed-off-by Jacob Keller <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 148 +++++++++++++++---- ------ 1 file changed, 89 insertions(+), 59 deletions(-)
PATCH 3/12 i40e: move ethtool stats boiler plate code to i40e_ethtool_stats.h
In reply to Alice MichaelFrom: Jacob Keller <[email protected]>
Move the boiler plate structures and helper functions we recently added into their own header file, so that the complete collection is located together.
--- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 182 +---------------- .../net/ethernet/intel/i40e/i40e_ethtool_stats.h | 221 +++++++++++++++++++++ 2 files changed, 222 insertions(+), 181 deletions(-) create mode 100644 drivers/net/ethernet/intel/i40e/i40e_ethtool_stats.h
drivers/net/ethernet/intel/i40e/i40e_ethtool.c +1 -181
@@ -6,25 +6,8 @@#include "i40e.h" #include "i40e_diag.h" -struct i40e_stats { -/* The stat_string is expected to be a format string formatted using -* vsnprintf by i40e_add_stat_strings. Every member of a stats array -* should use the same format specifiers as they will be formatted -* using the same variadic arguments. -*/ -char stat_string[ETH_GSTRING_LEN ]; -int sizeof_stat; -int stat_offset; -}; - -#define I40E_STAT (_type, _name, _stat) { \ - .stat_string = _name, \ - .sizeof_stat = FIELD_SIZEOF(_type, _stat), \ - .stat_offset = offsetof(_type, _stat) \ -} +#include "i40e_ethtool_stats.h" -#define I40E_NETDEV_STAT (_net_stat) \ - I40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat)#define I40E_PF_STAT (_name, _stat) \ I40E_STAT(struct i40e_pf, _name, _stat)#define I40E_VSI_STAT (_name, _stat) \
@@ -173,11 +156,6 @@ static const struct i40e_stats i40e_gstrings_pfc_stats[] = { I40E_PFC_STAT("port.rx_priority_%u_xon_2_xoff", priority_xon_2_xoff), }; -static const struct i40e_stats i40e_gstrings_queue_stats[] = { -I40E_QUEUE_STAT ("%s-%u.packets" , stats.packets), -I40E_QUEUE_STAT ("%s-%u.bytes" , stats.bytes), -}; -#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)
@@ -1750,128 +1728,6 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset) }/** -* i40e_add_one_ethtool_stat - copy the stat into the supplied buffer -* @data: location to store the stat value -* @pointer: basis for where to copy from -* @stat: the stat definition -* -* Copies the stat data defined by the pointer and stat structure pair into -* the memory supplied as data. Used to implement i40e_add_ethtool_stats and -* i40e_add_queue_stats. If the pointer is null, data will be zero'd. -*/ -static inline void -i40e_add_one_ethtool_stat (u64 *data,void *pointer, -const struct i40e_stats *stat) -{ -char *p; - -if (!pointer) { -/* ensure that the ethtool data buffer is zero'd for any stats -* which don't have a valid pointer. -*/ - *data =0 ; -return ; - } - - p = (char *)pointer + stat->stat_offset; -switch (stat->sizeof_stat) { -case sizeof (u64): - *data = *((u64 *)p); -break ; -case sizeof (u32): - *data = *((u32 *)p); -break ; -case sizeof (u16): - *data = *((u16 *)p); -break ; -case sizeof (u8): - *data = *((u8 *)p); -break ; -default : -WARN_ONCE (1 ,"unexpected stat size for %s" , - stat->stat_string); - *data =0 ; - } -} - -/** -* __i40e_add_ethtool_stats - copy stats into the ethtool supplied buffer -* @data: ethtool stats buffer -* @pointer: location to copy stats from -* @stats: array of stats to copy -* @size: the size of the stats definition -* -* Copy the stats defined by the stats array using the pointer as a base into -* the data buffer supplied by ethtool. Updates the data pointer to point to -* the next empty location for successive calls to __i40e_add_ethtool_stats. -* If pointer is null, set the data values to zero and update the pointer to -* skip these stats. -**/ -static inline void -__i40e_add_ethtool_stats (u64 **data,void *pointer, -const struct i40e_stats stats[], -const unsigned int size) -{ -unsigned int i; - -for (i =0 ; i < size; i++) -i40e_add_one_ethtool_stat ((*data)++, pointer, &stats[i]); -} - -/** -* i40e_add_ethtool_stats - copy stats into ethtool supplied buffer -* @data: ethtool stats buffer -* @pointer: location where stats are stored -* @stats: static const array of stat definitions -* -* Macro to ease the use of __i40e_add_ethtool_stats by taking a static -* constant stats array and passing the ARRAY_SIZE(). This avoids typos by -* ensuring that we pass the size associated with the given stats array. -* Assumes that stats is an array. -**/ -#define i40e_add_ethtool_stats (data, pointer, stats) \ - __i40e_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats)) - -/** -* i40e_add_queue_stats - copy queue statistics into supplied buffer -* @data: ethtool stats buffer -* @ring: the ring to copy -* -* Queue statistics must be copied while protected by -* u64_stats_fetch_begin_irq, so we can't directly use i40e_add_ethtool_stats. -* Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the -* ring pointer is null, zero out the queue stat values and update the data -* pointer. Otherwise safely copy the stats from the ring into the supplied -* buffer and update the data pointer when finished. -* -* This function expects to be called while under rcu_read_lock(). -**/ -static inline void -i40e_add_queue_stats (u64 **data,struct i40e_ring *ring) -{ -const unsigned int size =ARRAY_SIZE (i40e_gstrings_queue_stats); -const struct i40e_stats *stats = i40e_gstrings_queue_stats; -unsigned int start; -unsigned int i; - -/* To avoid invalid statistics values, ensure that we keep retrying -* the copy until we get a consistent value according to -* u64_stats_fetch_retry_irq. But first, make sure our ring is -* non-null before attempting to access its syncp. -*/ -do { - start = !ring ?0 :u64_stats_fetch_begin_irq (&ring->syncp); -for (i =0 ; i < size; i++) { -i40e_add_one_ethtool_stat (&(*data)[i], ring, - &stats[i]); - } - }while (ring &&u64_stats_fetch_retry_irq (&ring->syncp, start)); - -/* Once we successfully copy the stats in, update the data pointer */ - data += size; -} - -/** * i40e_get_pfc_stats - copy HW PFC statistics to formatted structure * @pf: the PF device structure * @i: the priority value to copy
@@ -1966,42 +1822,6 @@ static void i40e_get_ethtool_stats(struct net_device *netdev, }/** -* __i40e_add_stat_strings - copy stat strings into ethtool buffer -* @p: ethtool supplied buffer -* @stats: stat definitions array -* @size: size of the stats array -* -* Format and copy the strings described by stats into the buffer pointed at -* by p. -**/ -static void __i40e_add_stat_strings (u8 **p,const struct i40e_stats stats[], -const unsigned int size, ...) -{ -unsigned int i; - -for (i =0 ; i < size; i++) { -va_list args; - -va_start (args, size); -vsnprintf (*p,ETH_GSTRING_LEN , stats[i].stat_string, args); - *p +=ETH_GSTRING_LEN ; -va_end (args); - } -} - -/** -* 40e_add_stat_strings - copy stat strings into ethtool buffer -* @p: ethtool supplied buffer -* @stats: stat definitions array -* -* Format and copy the strings described by the const static stats value into -* the buffer pointed@by p. Assumes that stats can have ARRAY_SIZE called -* for it. -**/ -#define i40e_add_stat_strings (p, stats, ...) \ - __i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__) - -/** * i40e_get_stat_strings - copy stat strings into supplied buffer * @netdev: the netdev to collect strings for * @data: supplied buffer to copy strings into
drivers/net/ethernet/intel/i40e/i40e_ethtool_stats.h new file +221 -0
221 lines not on this page · raw message
Signature · 1 line
2.9.5
Bowers
PATCH 3/12 i40e: move ethtool stats boiler plate code to i40e_ethtool_stats.h
Quoted 14 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:12 AM
To: Michael, Alice <[email protected]>; intel-wired-
lan at lists.osuosl.org
Subject: [Intel-wired-lan] [next PATCH S95 03/12] i40e: move ethtool stats boiler plate code toi40e_ethtool_stats.hFrom: Jacob Keller <[email protected]>
Move the boiler plate structures and helper functions we recently added into their own header file, so that the complete collection is located together.
Quoted 7 lines
Signed-off-by Jacob Keller <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 182 +---------------- .../net/ethernet/intel/i40e/i40e_ethtool_stats.h | 221 +++++++++++++++++++++ 2 files changed, 222 insertions(+), 181 deletions(-) create mode 100644
drivers/net/ethernet/intel/i40e/i40e_ethtool_stats.h
PATCH 4/12 i40evf: update ethtool stats code and use helper functions
In reply to Alice MichaelFrom: Jacob Keller <[email protected]>
Fix a bug in the way we handled VF queues, by always showing stats for the maximum number of queues, even if they aren't allocated. It is not safe to change the number of strings reported to ethtool, as grabbing statistics occurs over multiple ethtool ops for which the rtnl_lock() cannot be held the entire time.
Avoid this by always reporting queue stats for the maximum number of queues in the netdevice. Share some of the helper functionality for adding stats with the PF code in i40e_ethtool_stats.h
This should reduce the chance of potential future bugs, and make adding new statistics easier.
Note for the queue stats, unlike the PF driver we do not keep an array of queue pointers, but an array of queues, so care must be taken to avoid accessing queue memory that hasn't yet been allocated.
--- .../net/ethernet/intel/i40evf/i40e_ethtool_stats.h | 221 +++++++++++++++++++++ drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 137 +++++++------ 2 files changed, 298 insertions(+), 60 deletions(-) create mode 100644 drivers/net/ethernet/intel/i40evf/i40e_ethtool_stats.h
drivers/net/ethernet/intel/i40evf/i40e_ethtool_stats.h new file +221 -0
@@ -0,0 +1,221 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2013 - 2018 Intel Corporation. */ + +/* ethtool statistics helpers */ + +/** +* struct i40e_stats - definition for an ethtool statistic +* @stat_string: statistic name to display in ethtool -S output +* @sizeof_stat: the sizeof() the stat, must be no greater than sizeof(u64) +* @stat_offset: offsetof() the stat from a base pointer +* +* This structure defines a statistic to be added to the ethtool stats buffer. +* It defines a statistic as offset from a common base pointer. Stats should +* be defined in constant arrays using the I40E_STAT macro, with every element +* of the array using the same _type for calculating the sizeof_stat and +* stat_offset. +* +* The @sizeof_stat is expected to be sizeof(u8), sizeof(u16), sizeof(u32) or +* sizeof(u64). Other sizes are not expected and will produce a WARN_ONCE from +* the i40e_add_ethtool_stat() helper function. +* +* The @stat_string is interpreted as a format string, allowing formatted +* values to be inserted while looping over multiple structures for a given +* statistics array. Thus, every statistic string in an array should have the +* same type and number of format specifiers, to be formatted by variadic +* arguments to the i40e_add_stat_string() helper function. +**/ +struct i40e_stats { +char stat_string[ETH_GSTRING_LEN ]; +int sizeof_stat; +int stat_offset; +}; + +/* Helper macro to define an i40e_stat structure with proper size and type. +* Use this when defining constant statistics arrays. Note that @_type expects +* only a type name and is used multiple times. +*/ +#define I40E_STAT (_type, _name, _stat) { \ + .stat_string = _name, \ + .sizeof_stat = FIELD_SIZEOF(_type, _stat), \ + .stat_offset = offsetof(_type, _stat) \ +} + +/* Helper macro for defining some statistics directly copied from the netdev +* stats structure. +*/ +#define I40E_NETDEV_STAT (_net_stat) \ + I40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat) + +/* Helper macro for defining some statistics related to queues */ +#define I40E_QUEUE_STAT (_name, _stat) \ + I40E_STAT(struct i40e_ring, _name, _stat) + +/* Stats associated with a Tx or Rx ring */ +static const struct i40e_stats i40e_gstrings_queue_stats[] = { +I40E_QUEUE_STAT ("%s-%u.packets" , stats.packets), +I40E_QUEUE_STAT ("%s-%u.bytes" , stats.bytes), +}; + +/** +* i40evf_add_one_ethtool_stat - copy the stat into the supplied buffer +* @data: location to store the stat value +* @pointer: basis for where to copy from +* @stat: the stat definition +* +* Copies the stat data defined by the pointer and stat structure pair into +* the memory supplied as data. Used to implement i40e_add_ethtool_stats and +* i40evf_add_queue_stats. If the pointer is null, data will be zero'd. +*/ +static inline void +i40evf_add_one_ethtool_stat (u64 *data,void *pointer, +const struct i40e_stats *stat) +{ +char *p; + +if (!pointer) { +/* ensure that the ethtool data buffer is zero'd for any stats +* which don't have a valid pointer. +*/ + *data =0 ; +return ; + } + + p = (char *)pointer + stat->stat_offset; +switch (stat->sizeof_stat) { +case sizeof (u64): + *data = *((u64 *)p); +break ; +case sizeof (u32): + *data = *((u32 *)p); +break ; +case sizeof (u16): + *data = *((u16 *)p); +break ; +case sizeof (u8): + *data = *((u8 *)p); +break ; +default : +WARN_ONCE (1 ,"unexpected stat size for %s" , + stat->stat_string); + *data =0 ; + } +} + +/** +* __i40evf_add_ethtool_stats - copy stats into the ethtool supplied buffer +* @data: ethtool stats buffer +* @pointer: location to copy stats from +* @stats: array of stats to copy +* @size: the size of the stats definition +* +* Copy the stats defined by the stats array using the pointer as a base into +* the data buffer supplied by ethtool. Updates the data pointer to point to +* the next empty location for successive calls to __i40evf_add_ethtool_stats. +* If pointer is null, set the data values to zero and update the pointer to +* skip these stats. +**/ +static inline void +__i40evf_add_ethtool_stats (u64 **data,void *pointer, +const struct i40e_stats stats[], +const unsigned int size) +{ +unsigned int i; + +for (i =0 ; i < size; i++) +i40evf_add_one_ethtool_stat ((*data)++, pointer, &stats[i]); +} + +/** +* i40e_add_ethtool_stats - copy stats into ethtool supplied buffer +* @data: ethtool stats buffer +* @pointer: location where stats are stored +* @stats: static const array of stat definitions +* +* Macro to ease the use of __i40evf_add_ethtool_stats by taking a static +* constant stats array and passing the ARRAY_SIZE(). This avoids typos by +* ensuring that we pass the size associated with the given stats array. +* +* The parameter @stats is evaluated twice, so parameters with side effects +* should be avoided. +**/ +#define i40e_add_ethtool_stats (data, pointer, stats) \ + __i40evf_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats)) + +/** +* i40evf_add_queue_stats - copy queue statistics into supplied buffer +* @data: ethtool stats buffer +* @ring: the ring to copy +* +* Queue statistics must be copied while protected by +* u64_stats_fetch_begin_irq, so we can't directly use i40e_add_ethtool_stats. +* Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the +* ring pointer is null, zero out the queue stat values and update the data +* pointer. Otherwise safely copy the stats from the ring into the supplied +* buffer and update the data pointer when finished. +* +* This function expects to be called while under rcu_read_lock(). +**/ +static inline void +i40evf_add_queue_stats (u64 **data,struct i40e_ring *ring) +{ +const unsigned int size =ARRAY_SIZE (i40e_gstrings_queue_stats); +const struct i40e_stats *stats = i40e_gstrings_queue_stats; +unsigned int start; +unsigned int i; + +/* To avoid invalid statistics values, ensure that we keep retrying +* the copy until we get a consistent value according to +* u64_stats_fetch_retry_irq. But first, make sure our ring is +* non-null before attempting to access its syncp. +*/ +do { + start = !ring ?0 :u64_stats_fetch_begin_irq (&ring->syncp); +for (i =0 ; i < size; i++) { +i40evf_add_one_ethtool_stat (&(*data)[i], ring, + &stats[i]); + } + }while (ring &&u64_stats_fetch_retry_irq (&ring->syncp, start)); + +/* Once we successfully copy the stats in, update the data pointer */ + *data += size; +} + +/** +* __i40e_add_stat_strings - copy stat strings into ethtool buffer +* @p: ethtool supplied buffer +* @stats: stat definitions array +* @size: size of the stats array +* +* Format and copy the strings described by stats into the buffer pointed at +* by p. +**/ +static void __i40e_add_stat_strings (u8 **p,const struct i40e_stats stats[], +const unsigned int size, ...) +{ +unsigned int i; + +for (i =0 ; i < size; i++) { +va_list args; + +va_start (args, size); +vsnprintf (*p,ETH_GSTRING_LEN , stats[i].stat_string, args); + *p +=ETH_GSTRING_LEN ; +va_end (args); + } +} + +/** +* 40e_add_stat_strings - copy stat strings into ethtool buffer +* @p: ethtool supplied buffer +* @stats: stat definitions array +* +* Format and copy the strings described by the const static stats value into +* the buffer pointed@by p. +* +* The parameter @stats is evaluated twice, so parameters with side effects +* should be avoided. Additionally, stats must be an array such that +* ARRAY_SIZE can be called on it. +**/ +#define i40e_add_stat_strings (p, stats, ...) \ + __i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)
drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c +77 -60
179 lines not on this page · raw message
Signature · 1 line
2.9.5
Bowers
PATCH 4/12 i40evf: update ethtool stats code and use helper functions
Quoted 28 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:12 AM
To: Michael, Alice <[email protected]>; intel-wired- lan at lists.osuosl.org
Subject: [Intel-wired-lan] [next PATCH S95 04/12] i40evf: update ethtool stats code and use helper functionsFrom: Jacob Keller <[email protected]>
Fix a bug in the way we handled VF queues, by always showing stats for the maximum number of queues, even if they aren't allocated. It is not safe to change the number of strings reported to ethtool, as grabbing statistics occurs over multiple ethtool ops for which the
rtnl_lock()cannot be held the entire time.Avoid this by always reporting queue stats for the maximum number of queues in the netdevice. Share some of the helper functionality for adding stats with the PF code in
i40e_ethtool_stats.hThis should reduce the chance of potential future bugs, and make adding new statistics easier.
Note for the queue stats, unlike the PF driver we do not keep an array of queue pointers, but an array of queues, so care must be taken to avoid accessing queue memory that hasn't yet been allocated.
Quoted 7 lines
Signed-off-by Jacob Keller <[email protected]>--- .../net/ethernet/intel/i40evf/i40e_ethtool_stats.h | 221 +++++++++++++++++++++ drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 137 +++++++------ 2 files changed, 298 insertions(+), 60 deletions(-) create mode 100644
drivers/net/ethernet/intel/i40evf/i40e_ethtool_stats.h
PATCH 5/12 i40evf: Change a VF mac without reloading the VF driver
In reply to Alice MichaelFrom: Pawe? Jab?o?ski <[email protected]> <[email protected]>
Add possibility to change a VF mac address from host side without reloading the VF driver on the guest side. Without this patch it is not possible to change the VF mac because executing i40evf_virtchnl_completion function with VIRTCHNL_OP_GET_VF_RESOURCES opcode resets the VF mac address to previous value.
--- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 8 +++++--- drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c | 11 +++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +5 -3
@@ -2458,7 +2458,7 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, !is_multicast_ether_addr(addr) && vf->pf_set_mac && !ether_addr_equal(addr, vf->default_lan_addr.addr)) {dev_err (&pf->pdev->dev, -"VF attempting to override administratively set MAC address, reload the VF driver to resume normal operation\n" ); +"VF attempting to override administratively set MAC address, bring down and up the VF interface to resume normal operation\n" );return -EPERM ; } }
@@ -3873,9 +3873,11 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) mac, vf_id); } -/* Force the VF driver stop so it has to reload with new MAC address */ +/* Force the VF interface down so it has to bring up with new MAC +* address +*/ i40e_vc_disable_vf (vf); -dev_info (&pf->pdev->dev,"Reload the VF driver to make this change effective.\n" ); +dev_info (&pf->pdev->dev,"Bring down and up the VF interface to make this change effective.\n" ); error_param:return ret;
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +9 -2
@@ -1330,8 +1330,15 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,sizeof (struct virtchnl_vsi_resource );memcpy (adapter->vf_res, msg,min (msglen, len));i40e_vf_parse_hw_config (&adapter->hw, adapter->vf_res); -/* restore current mac address */ -ether_addr_copy (adapter->hw.mac.addr, netdev->dev_addr); +if (is_zero_ether_addr (adapter->hw.mac.addr)) { +/* restore current mac address */ +ether_addr_copy (adapter->hw.mac.addr, netdev->dev_addr); + }else { +/* refresh current mac address if changed */ +ether_addr_copy (netdev->dev_addr, adapter->hw.mac.addr); +ether_addr_copy (netdev->perm_addr, + adapter->hw.mac.addr); + }i40evf_process_config (adapter); }break ;
Signature · 1 line
2.9.5
Bowers
PATCH 5/12 i40evf: Change a VF mac without reloading the VF driver
Setting the VF mac to something arbitrary works, however setting it back to 00:00:00:00:00:00 does NOT set it back to all zeroes, nor does it trigger random MAC generation (dmesg shows "removing MAC on VF 0" and the message to bring the interface down and back up, however dmesg does not report "invalid MAC address, using random" and "ip ad show"
still shows the 00:11:22:33:44:55 MAC that was set.
Quoted 98 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:12 AM
To: Michael, Alice <[email protected]>; intel-wired- lan at lists.osuosl.org
Cc: Pawe? Jab?o?ski <"[email protected]"@intel.com>; Pawe? Jab?o?ski <[email protected]>
Subject: [Intel-wired-lan] [next PATCH S95 05/12] i40evf: Change a VF mac without reloading the VF driverFrom: Pawe? Jab?o?ski <[email protected]>
<[email protected]>Add possibility to change a VF mac address from host side without reloading the VF driver on the guest side. Without this patch it is not possible to change the VF mac because executing
i40evf_virtchnl_completionfunction withVIRTCHNL_OP_GET_VF_RESOURCESopcode resets the VF mac address to previous value.Signed-off-by Pawe? Jab?o?ski <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 8 +++++--- drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c | 11 +++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-)drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +1
-1@@ -2458,7 +2458,7 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, !is_multicast_ether_addr(addr) && vf->pf_set_mac && !ether_addr_equal(addr, vf->default_lan_addr.addr)) {dev_err (&pf->pdev->dev, - "VF attempting to override administratively set MAC address, reload the VF driver to resume normal operation\n"); + "VF attempting to override administrativelyset MAC address, bring
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +5
-2+down and up the VF interface to resume normal operation\n");return -EPERM ; } }@@ -3873,9 +3873,11 @@ int i40e_ndo_set_vf_mac(struct net_device*netdev, int vf_id, u8 *mac) mac, vf_id); } -/* Force the VF driver stop so it has to reload with new MAC address */ +/* Force the VF interface down so it has to bring up with new MAC +* address +*/ i40e_vc_disable_vf (vf); - dev_info(&pf->pdev->dev, "Reload the VF driver to make this change effective.\n"); + dev_info(&pf->pdev->dev, "Bring down and up the VF interface tomake
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +1
-0+this change effective.\n"); error_param:return ret;drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +6
-2@@ -1330,8 +1330,15 @@ void i40evf_virtchnl_completion(structi40evf_adapter *adapter, sizeof(struct virtchnl_vsi_resource);memcpy (adapter->vf_res, msg,min (msglen, len));i40e_vf_parse_hw_config (&adapter->hw, adapter->vf_res); -/* restore current mac address */ -ether_addr_copy (adapter->hw.mac.addr, netdev- >dev_addr); +if (is_zero_ether_addr (adapter->hw.mac.addr)) { +/* restore current mac address */ +ether_addr_copy (adapter->hw.mac.addr, netdev- >dev_addr); + }else { +/* refresh current mac address if changed */ + ether_addr_copy(netdev->dev_addr, adapter-Quoted 1 line
hw.mac.addr);
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +3
-1+ether_addr_copy (netdev->perm_addr, + adapter->hw.mac.addr); + }i40evf_process_config (adapter); }break ; --2.9.5
_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan at osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
Bowers
PATCH 5/12 i40evf: Change a VF mac without reloading the VF driver
Quoted 31 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Bowers, AndrewX
Sent: Tuesday, August 21, 2018 12:29 PM
To: Michael, Alice <[email protected]>; Michael, Alice <[email protected]>; intel-wired-lan at lists.osuosl.org
Cc: Pawel Jablonski <"[email protected]"@intel.com>; Pawel Jablonski <[email protected]>
Subject: Re: [Intel-wired-lan] [next PATCH S95 05/12] i40evf: Change a VF mac without reloading the VF driverSetting the VF mac to something arbitrary works, however setting it back to 00:00:00:00:00:00 does NOT set it back to all zeroes, nor does it trigger random MAC generation (dmesg shows "removing MAC on VF 0" and the message to bring the interface down and back up, however dmesg does not report "invalid MAC address, using random" and "ip ad show"
still shows the 00:11:22:33:44:55 MAC that was set.Quoted 12 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:12 AM
To: Michael, Alice <[email protected]>; intel-wired- lan at lists.osuosl.org
Cc: Pawe? Jab?o?ski <"[email protected]"@intel.com>; Pawe? Jab?o?ski <[email protected]>
Subject: [Intel-wired-lan] [next PATCH S95 05/12] i40evf: Change a VF mac without reloading the VF driver
Quoted 15 lines
Quoted 7 lines
From: Pawe? Jab?o?ski <[email protected]>
<[email protected]>Add possibility to change a VF mac address from host side without reloading the VF driver on the guest side. Without this patch it is not possible to change the VF mac because executing
i40evf_virtchnl_completionfunction with
VIRTCHNL_OP_GET_VF_RESOURCESQuoted 7 lines
opcode resets the VF mac address to previous value.
Signed-off-by Pawe? Jab?o?ski <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 8 +++++--- drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c | 11 +++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-)
PATCH 6/12 i40e: fix condition of WARN_ONCE for stat strings
In reply to Alice MichaelFrom: Jacob Keller <[email protected]>
Commit 9b10df596bd4 ("i40e: use WARN_ONCE to replace the commented BUG_ON size check") introduced a warning check to make sure that the size of the stat strings was always the expected value. This code accidentally inverted the check of the data pointer. Fix this so that we accurately count the size of the stats we copied in.
This fixes an erroneous WARN kernel splat that occurs when requesting ethtool statistics.
--- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/i40e/i40e_ethtool.c +1 -1
@@ -1863,7 +1863,7 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)for (i =0 ; i <I40E_MAX_USER_PRIORITY ; i++)i40e_add_stat_strings (&data, i40e_gstrings_pfc_stats, i); -WARN_ONCE (p - data !=i40e_get_stats_count (netdev) *ETH_GSTRING_LEN , +WARN_ONCE (data - p !=i40e_get_stats_count (netdev) *ETH_GSTRING_LEN ,"stat strings count mismatch!" ); }
Signature · 1 line
2.9.5
Bowers
PATCH 6/12 i40e: fix condition of WARN_ONCE for stat strings
Quoted 17 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:12 AM
To: Michael, Alice <[email protected]>; intel-wired- lan at lists.osuosl.org
Subject: [Intel-wired-lan] [next PATCH S95 06/12] i40e: fix condition ofWARN_ONCEfor stat stringsFrom: Jacob Keller <[email protected]>
Commit
9b10df596bd4("i40e: useWARN_ONCEto replace the commentedBUG_ONsize check") introduced a warning check to make sure that the size of the stat strings was always the expected value. This code accidentally inverted the check of the data pointer. Fix this so that we accurately count the size of the stats we copied in.
Quoted 7 lines
This fixes an erroneous WARN kernel splat that occurs when requesting ethtool statistics.
Signed-off-by Jacob Keller <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
PATCH 6/12 i40e: fix condition of WARN_ONCE for stat strings
In reply to Alice MichaelQuoted 8 lines · Alice Michael
From: Jacob Keller <[email protected]>
Commit
9b10df596bd4("i40e: useWARN_ONCEto replace the commentedBUG_ONsize check") introduced a warning check to make sure that the size of the stat strings was always the expected value. This code accidentally inverted the check of the data pointer. Fix this so that we accurately count the size of the stats we copied in.
Quoted 8 lines
This fixes an erroneous WARN kernel splat that occurs when requesting ethtool statistics.
Signed-off-by Jacob Keller <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
PATCH 7/12 i40e: Unset promiscuous settings on VF reset
In reply to Alice MichaelFrom: Mariusz Stachura <[email protected]>
This patch cleans up promiscuous configuration when a VF reset occurs. Previously the promiscuous mode settings were still there after the VF driver removal.
--- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 267 ++++++++++++--------- 1 file changed, 157 insertions(+), 110 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +157 -110
@@ -1084,6 +1084,136 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf)return -EIO ; } +static inline int i40e_getnum_vf_vsi_vlan_filters (struct i40e_vsi *vsi); + +/** +* i40e_config_vf_promiscuous_mode +* @vf: pointer to the VF info +* @vsi_id: VSI id +* @allmulti: set MAC L2 layer multicast promiscuous enable/disable +* @alluni: set MAC L2 layer unicast promiscuous enable/disable +* +* Called from the VF to configure the promiscuous mode of +* VF vsis and from the VF reset path to reset promiscuous mode. +**/ +static i40e_status i40e_config_vf_promiscuous_mode (struct i40e_vf *vf, +u16 vsi_id, +bool allmulti, +bool alluni) +{ +i40e_status aq_ret =0 ; +struct i40e_pf *pf = vf->pf; +struct i40e_hw *hw = &pf->hw; +struct i40e_mac_filter *f; +struct i40e_vsi *vsi; +int bkt; + + vsi =i40e_find_vsi_from_id (pf, vsi_id); +if (!i40e_vc_isvalid_vsi_id (vf, vsi_id) || !vsi) +return I40E_ERR_PARAM ; + +if (!test_bit (I40E_VIRTCHNL_VF_CAP_PRIVILEGE , &vf->vf_caps)) { +dev_err (&pf->pdev->dev, +"Unprivileged VF %d is attempting to configure promiscuous mode\n" , + vf->vf_id); +/* Lie to the VF on purpose. */ +return 0 ; + } + +if (vf->port_vlan_id) { + aq_ret =i40e_aq_set_vsi_mc_promisc_on_vlan (hw, vsi->seid, + allmulti, + vf->port_vlan_id, +NULL ); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"VF %d failed to set multicast promiscuous mode err %s aq_err %s\n" , + vf->vf_id, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err)); +return aq_ret; + } + + aq_ret =i40e_aq_set_vsi_uc_promisc_on_vlan (hw, vsi->seid, + alluni, + vf->port_vlan_id, +NULL ); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"VF %d failed to set unicast promiscuous mode err %s aq_err %s\n" , + vf->vf_id, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err)); + } +return aq_ret; + }else if (i40e_getnum_vf_vsi_vlan_filters (vsi)) { +hash_for_each (vsi->mac_filter_hash, bkt, f, hlist) { +if (f->vlan <0 || f->vlan >I40E_MAX_VLANID ) +continue ; + aq_ret =i40e_aq_set_vsi_mc_promisc_on_vlan (hw, + vsi->seid, + allmulti, + f->vlan, +NULL ); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"Could not add VLAN %d to multicast promiscuous domain err %s aq_err %s\n" , + f->vlan, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err)); + } + + aq_ret =i40e_aq_set_vsi_uc_promisc_on_vlan (hw, + vsi->seid, + alluni, + f->vlan, +NULL ); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"Could not add VLAN %d to Unicast promiscuous domain err %s aq_err %s\n" , + f->vlan, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err)); + } + } +return aq_ret; + } + aq_ret =i40e_aq_set_vsi_multicast_promiscuous (hw, vsi->seid, allmulti, +NULL ); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"VF %d failed to set multicast promiscuous mode err %s aq_err %s\n" , + vf->vf_id, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err)); +return aq_ret; + } + + aq_ret =i40e_aq_set_vsi_unicast_promiscuous (hw, vsi->seid, alluni, +NULL , true); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"VF %d failed to set unicast promiscuous mode err %s aq_err %s\n" , + vf->vf_id, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err)); + } + +return aq_ret; +} +/** * i40e_trigger_vf_reset * @vf: pointer to the VF structure
@@ -1145,6 +1275,9 @@ static void i40e_cleanup_reset_vf(struct i40e_vf *vf)struct i40e_hw *hw = &pf->hw;u32 reg; +/* disable promisc modes in case they were enabled */ +i40e_config_vf_promiscuous_mode (vf, vf->lan_vsi_id, false, false); +/* free VF resources to begin resetting the VSI state */ i40e_free_vf_res (vf);
@@ -1851,132 +1984,46 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf,struct virtchnl_promisc_info *info = (struct virtchnl_promisc_info *)msg;struct i40e_pf *pf = vf->pf; -struct i40e_hw *hw = &pf->hw; -struct i40e_mac_filter *f;i40e_status aq_ret =0 ;bool allmulti = false; -struct i40e_vsi *vsi;bool alluni = false; -int aq_err =0 ; -int bkt; - vsi =i40e_find_vsi_from_id (pf, info->vsi_id); -if (!test_bit (I40E_VF_STATE_ACTIVE , &vf->vf_states) || - !i40e_vc_isvalid_vsi_id (vf, info->vsi_id) || - !vsi) { - aq_ret =I40E_ERR_PARAM ; - goto error_param; - } -if (!test_bit (I40E_VIRTCHNL_VF_CAP_PRIVILEGE , &vf->vf_caps)) { -dev_err (&pf->pdev->dev, -"Unprivileged VF %d is attempting to configure promiscuous mode\n" , - vf->vf_id); -/* Lie to the VF on purpose. */ - aq_ret =0 ; - goto error_param; - } +if (!test_bit (I40E_VF_STATE_ACTIVE , &vf->vf_states)) +return I40E_ERR_PARAM ; +/* Multicast promiscuous handling*/ if (info->flags &FLAG_VF_MULTICAST_PROMISC ) allmulti = true; -if (vf->port_vlan_id) { - aq_ret =i40e_aq_set_vsi_mc_promisc_on_vlan (hw, vsi->seid, - allmulti, - vf->port_vlan_id, -NULL ); - }else if (i40e_getnum_vf_vsi_vlan_filters (vsi)) { -hash_for_each (vsi->mac_filter_hash, bkt, f, hlist) { -if (f->vlan <0 || f->vlan >I40E_MAX_VLANID ) -continue ; - aq_ret =i40e_aq_set_vsi_mc_promisc_on_vlan (hw, - vsi->seid, - allmulti, - f->vlan, -NULL ); - aq_err = pf->hw.aq.asq_last_status; -if (aq_ret) { -dev_err (&pf->pdev->dev, -"Could not add VLAN %d to multicast promiscuous domain err %s aq_err %s\n" , - f->vlan, -i40e_stat_str (&pf->hw, aq_ret), -i40e_aq_str (&pf->hw, aq_err)); -break ; - } - } - }else { - aq_ret =i40e_aq_set_vsi_multicast_promiscuous (hw, vsi->seid, - allmulti,NULL ); - aq_err = pf->hw.aq.asq_last_status; -if (aq_ret) { -dev_err (&pf->pdev->dev, -"VF %d failed to set multicast promiscuous mode err %s aq_err %s\n" , - vf->vf_id, -i40e_stat_str (&pf->hw, aq_ret), -i40e_aq_str (&pf->hw, aq_err)); - goto error_param; - } - } - +if (info->flags &FLAG_VF_UNICAST_PROMISC ) + alluni = true; + aq_ret =i40e_config_vf_promiscuous_mode (vf, info->vsi_id, allmulti, + alluni);if (!aq_ret) { -dev_info (&pf->pdev->dev, -"VF %d successfully set multicast promiscuous mode\n" , - vf->vf_id); -if (allmulti) +if (allmulti) { +dev_info (&pf->pdev->dev, +"VF %d successfully set multicast promiscuous mode\n" , + vf->vf_id);set_bit (I40E_VF_STATE_MC_PROMISC , &vf->vf_states); -else + }else { +dev_info (&pf->pdev->dev, +"VF %d successfully unset multicast promiscuous mode\n" , + vf->vf_id);clear_bit (I40E_VF_STATE_MC_PROMISC , &vf->vf_states); - } - -if (info->flags &FLAG_VF_UNICAST_PROMISC ) - alluni = true; -if (vf->port_vlan_id) { - aq_ret =i40e_aq_set_vsi_uc_promisc_on_vlan (hw, vsi->seid, - alluni, - vf->port_vlan_id, -NULL ); - }else if (i40e_getnum_vf_vsi_vlan_filters (vsi)) { -hash_for_each (vsi->mac_filter_hash, bkt, f, hlist) { -if (f->vlan <0 || f->vlan >I40E_MAX_VLANID ) -continue ; - aq_ret =i40e_aq_set_vsi_uc_promisc_on_vlan (hw, - vsi->seid, - alluni, - f->vlan, -NULL ); - aq_err = pf->hw.aq.asq_last_status; -if (aq_ret) -dev_err (&pf->pdev->dev, -"Could not add VLAN %d to Unicast promiscuous domain err %s aq_err %s\n" , - f->vlan, -i40e_stat_str (&pf->hw, aq_ret), -i40e_aq_str (&pf->hw, aq_err)); } - }else { - aq_ret =i40e_aq_set_vsi_unicast_promiscuous (hw, vsi->seid, - alluni,NULL , - true); - aq_err = pf->hw.aq.asq_last_status; -if (aq_ret) { -dev_err (&pf->pdev->dev, -"VF %d failed to set unicast promiscuous mode %8.8x err %s aq_err %s\n" , - vf->vf_id, info->flags, -i40e_stat_str (&pf->hw, aq_ret), -i40e_aq_str (&pf->hw, aq_err)); - goto error_param; - } - } - -if (!aq_ret) { -dev_info (&pf->pdev->dev, -"VF %d successfully set unicast promiscuous mode\n" , - vf->vf_id); -if (alluni) +if (alluni) { +dev_info (&pf->pdev->dev, +"VF %d successfully set unicast promiscuous mode\n" , + vf->vf_id);set_bit (I40E_VF_STATE_UC_PROMISC , &vf->vf_states); -else + }else { +dev_info (&pf->pdev->dev, +"VF %d successfully unset unicast promiscuous mode\n" , + vf->vf_id);clear_bit (I40E_VF_STATE_UC_PROMISC , &vf->vf_states); + } } -error_param:/* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
Signature · 1 line
2.9.5
PATCH 7/12 i40e: Unset promiscuous settings on VF reset
Quoted 42 lines · Alice Michael
From: Mariusz Stachura <[email protected]>
This patch cleans up promiscuous configuration when a VF reset occurs. Previously the promiscuous mode settings were still there after the VF driver removal.
Signed-off-by Mariusz Stachura <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 267 ++++++++++++--------- 1 file changed, 157 insertions(+), 110 deletions(-)drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +23
-0@@ -1084,6 +1084,136 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf)return -EIO ; } +static inline int i40e_getnum_vf_vsi_vlan_filters (struct i40e_vsi *vsi); + +/** +* i40e_config_vf_promiscuous_mode +* @vf: pointer to the VF info +* @vsi_id: VSI id +* @allmulti: set MAC L2 layer multicast promiscuous enable/disable +* @alluni: set MAC L2 layer unicast promiscuous enable/disable +* +* Called from the VF to configure the promiscuous mode of +* VF vsis and from the VF reset path to reset promiscuous mode. +**/ +static i40e_status i40e_config_vf_promiscuous_mode (struct i40e_vf *vf, +u16 vsi_id, +bool allmulti, +bool alluni) +{ +i40e_status aq_ret =0 ; +struct i40e_pf *pf = vf->pf; +struct i40e_hw *hw = &pf->hw; +struct i40e_mac_filter *f; +struct i40e_vsi *vsi; +int bkt;
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c static int i40e_quiesce_vf_pci(struct i40e_vf *vf) · line 1119
Quoted 10 lines
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +10
-0+ + vsi =i40e_find_vsi_from_id (pf, vsi_id); +if (!i40e_vc_isvalid_vsi_id (vf, vsi_id) || !vsi) +return I40E_ERR_PARAM ; + +if (!test_bit (I40E_VIRTCHNL_VF_CAP_PRIVILEGE , &vf->vf_caps)) { +dev_err (&pf->pdev->dev, +"Unprivileged VF %d is attempting to configure promiscuous mode\n" , + vf->vf_id); +/* Lie to the VF on purpose. */
Can you explain why in the comment?
Quoted 21 lines
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +21
-0+return 0 ; + } + +if (vf->port_vlan_id) { + aq_ret =i40e_aq_set_vsi_mc_promisc_on_vlan (hw, vsi->seid, + allmulti, + vf->port_vlan_id, +NULL ); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"VF %d failed to set multicast promiscuous mode err %s aq_err %s\n" , + vf->vf_id, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err)); +return aq_ret; + } + + aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, vsi->seid, + alluni,
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c static int i40e_quiesce_vf_pci(struct i40e_vf *vf) · line 1150
Quoted 10 lines
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +10
-0+ vf->port_vlan_id, + NULL); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"VF %d failed to set unicast promiscuous mode err %s aq_err %s\n" , + vf->vf_id, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err));
If uc_promisc fails, perhaps you should undo the mc_promisc change? Of course, you might need to find out what it was before you set it to see if there was a change requested.
Quoted 24 lines
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +24
-0+ } +return aq_ret; + }else if (i40e_getnum_vf_vsi_vlan_filters (vsi)) { +hash_for_each (vsi->mac_filter_hash, bkt, f, hlist) { +if (f->vlan <0 || f->vlan >I40E_MAX_VLANID ) +continue ; + aq_ret =i40e_aq_set_vsi_mc_promisc_on_vlan (hw, + vsi->seid, + allmulti, + f->vlan, +NULL ); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"Could not add VLAN %d to multicast promiscuous domain err %s aq_err %s\n" , + f->vlan, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err)); + } + + aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, + vsi->seid, + alluni,
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c static int i40e_quiesce_vf_pci(struct i40e_vf *vf) · line 1184
Quoted 10 lines
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +10
-0+ f->vlan, + NULL); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"Could not add VLAN %d to Unicast promiscuous domain err %s aq_err %s\n" , + f->vlan, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err));
Undo the mc_promisc change?
Quoted 17 lines
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +17
-0+ } + } +return aq_ret; + } + aq_ret =i40e_aq_set_vsi_multicast_promiscuous (hw, vsi->seid, allmulti, +NULL ); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"VF %d failed to set multicast promiscuous mode err %s aq_err %s\n" , + vf->vf_id, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err)); +return aq_ret; + } +
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c static int i40e_quiesce_vf_pci(struct i40e_vf *vf) · line 1211
Quoted 10 lines
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +10
-0+ aq_ret =i40e_aq_set_vsi_unicast_promiscuous (hw, vsi->seid, alluni, +NULL , true); +if (aq_ret) { +int aq_err = pf->hw.aq.asq_last_status; + +dev_err (&pf->pdev->dev, +"VF %d failed to set unicast promiscuous mode err %s aq_err %s\n" , + vf->vf_id, +i40e_stat_str (&pf->hw, aq_ret), +i40e_aq_str (&pf->hw, aq_err));
Undo the mc_promisc change?
Quoted 157 lines
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +23
-108+ } + +return aq_ret; +} +/** * i40e_trigger_vf_reset * @vf: pointer to the VF structure @@ -1145,6 +1275,9 @@ static void i40e_cleanup_reset_vf(struct i40e_vf *vf)struct i40e_hw *hw = &pf->hw;u32 reg; +/* disable promisc modes in case they were enabled */ +i40e_config_vf_promiscuous_mode (vf, vf->lan_vsi_id, false, false); +/* free VF resources to begin resetting the VSI state */ i40e_free_vf_res (vf);@@ -1851,132 +1984,46 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf,struct virtchnl_promisc_info *info = (struct virtchnl_promisc_info *)msg;struct i40e_pf *pf = vf->pf; -struct i40e_hw *hw = &pf->hw; -struct i40e_mac_filter *f;i40e_status aq_ret =0 ;bool allmulti = false; -struct i40e_vsi *vsi;bool alluni = false; -int aq_err =0 ; -int bkt; - vsi =i40e_find_vsi_from_id (pf, info->vsi_id); -if (!test_bit (I40E_VF_STATE_ACTIVE , &vf->vf_states) || - !i40e_vc_isvalid_vsi_id (vf, info->vsi_id) || - !vsi) { - aq_ret =I40E_ERR_PARAM ; - goto error_param; - } -if (!test_bit (I40E_VIRTCHNL_VF_CAP_PRIVILEGE , &vf->vf_caps)) { -dev_err (&pf->pdev->dev, -"Unprivileged VF %d is attempting to configure promiscuous mode\n" , - vf->vf_id); -/* Lie to the VF on purpose. */ - aq_ret =0 ; - goto error_param; - } +if (!test_bit (I40E_VF_STATE_ACTIVE , &vf->vf_states)) +return I40E_ERR_PARAM ; +/* Multicast promiscuous handling*/ if (info->flags &FLAG_VF_MULTICAST_PROMISC ) allmulti = true; -if (vf->port_vlan_id) { - aq_ret =i40e_aq_set_vsi_mc_promisc_on_vlan (hw, vsi->seid, - allmulti, - vf->port_vlan_id, -NULL ); - }else if (i40e_getnum_vf_vsi_vlan_filters (vsi)) { -hash_for_each (vsi->mac_filter_hash, bkt, f, hlist) { -if (f->vlan <0 || f->vlan >I40E_MAX_VLANID ) -continue ; - aq_ret =i40e_aq_set_vsi_mc_promisc_on_vlan (hw, - vsi->seid, - allmulti, - f->vlan, -NULL ); - aq_err = pf->hw.aq.asq_last_status; -if (aq_ret) { -dev_err (&pf->pdev->dev, -"Could not add VLAN %d to multicast promiscuous domain err %s aq_err %s\n" , - f->vlan, -i40e_stat_str (&pf->hw, aq_ret), -i40e_aq_str (&pf->hw, aq_err)); -break ; - } - } - }else { - aq_ret =i40e_aq_set_vsi_multicast_promiscuous (hw, vsi->seid, - allmulti,NULL ); - aq_err = pf->hw.aq.asq_last_status; -if (aq_ret) { -dev_err (&pf->pdev->dev, -"VF %d failed to set multicast promiscuous mode err %s aq_err %s\n" , - vf->vf_id, -i40e_stat_str (&pf->hw, aq_ret), -i40e_aq_str (&pf->hw, aq_err)); - goto error_param; - } - } - +if (info->flags &FLAG_VF_UNICAST_PROMISC ) + alluni = true; + aq_ret =i40e_config_vf_promiscuous_mode (vf, info->vsi_id, allmulti, + alluni);if (!aq_ret) { -dev_info (&pf->pdev->dev, -"VF %d successfully set multicast promiscuous mode\n" , - vf->vf_id); -if (allmulti) +if (allmulti) { +dev_info (&pf->pdev->dev, +"VF %d successfully set multicast promiscuous mode\n" , + vf->vf_id);set_bit (I40E_VF_STATE_MC_PROMISC , &vf->vf_states); -else + }else { +dev_info (&pf->pdev->dev, +"VF %d successfully unset multicast promiscuous mode\n" , + vf->vf_id);clear_bit (I40E_VF_STATE_MC_PROMISC , &vf->vf_states); - } - -if (info->flags &FLAG_VF_UNICAST_PROMISC ) - alluni = true; -if (vf->port_vlan_id) { - aq_ret =i40e_aq_set_vsi_uc_promisc_on_vlan (hw, vsi->seid, - alluni, - vf->port_vlan_id, -NULL ); - }else if (i40e_getnum_vf_vsi_vlan_filters (vsi)) { -hash_for_each (vsi->mac_filter_hash, bkt, f, hlist) { -if (f->vlan <0 || f->vlan >I40E_MAX_VLANID ) -continue ; - aq_ret =i40e_aq_set_vsi_uc_promisc_on_vlan (hw, - vsi->seid, - alluni, - f->vlan, -NULL ); - aq_err = pf->hw.aq.asq_last_status; -if (aq_ret) -dev_err (&pf->pdev->dev, -"Could not add VLAN %d to Unicast promiscuous domain err %s aq_err %s\n" , - f->vlan, -i40e_stat_str (&pf->hw, aq_ret), -i40e_aq_str (&pf->hw, aq_err)); } - }else { - aq_ret =i40e_aq_set_vsi_unicast_promiscuous (hw, vsi->seid, - alluni,NULL , - true); - aq_err = pf->hw.aq.asq_last_status; -if (aq_ret) { -dev_err (&pf->pdev->dev, -"VF %d failed to set unicast promiscuous mode %8.8x err %s aq_err %s\n" , - vf->vf_id, info->flags, -i40e_stat_str (&pf->hw, aq_ret), -i40e_aq_str (&pf->hw, aq_err)); - goto error_param; - } - } - -if (!aq_ret) { -dev_info (&pf->pdev->dev, -"VF %d successfully set unicast promiscuous mode\n" , - vf->vf_id); -if (alluni)
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf, · line 2022
Quoted 10 lines
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +8
-1+if (alluni) { +dev_info (&pf->pdev->dev, +"VF %d successfully set unicast promiscuous mode\n" , + vf->vf_id);set_bit (I40E_VF_STATE_UC_PROMISC , &vf->vf_states); - else + }else { +dev_info (&pf->pdev->dev, +"VF %d successfully unset unicast promiscuous mode\n" , + vf->vf_id);
It looks to me that all these status messages are getting printed whether there actually was a change or not. In other words, if the unicast promisc was already on, and the VF again calls for it to be set, this will be printed again, even though there was no change in state. Is this what you intended?
sln
Quoted 9 lines
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +1
-1clear_bit (I40E_VF_STATE_UC_PROMISC , &vf->vf_states); + } } -error_param:/* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
Bowers
PATCH 7/12 i40e: Unset promiscuous settings on VF reset
In reply to Alice MichaelQuoted 15 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:12 AM
To: Michael, Alice <[email protected]>; intel-wired- lan at lists.osuosl.org
Subject: [Intel-wired-lan] [next PATCH S95 07/12] i40e: Unset promiscuous settings on VF resetFrom: Mariusz Stachura <[email protected]>
This patch cleans up promiscuous configuration when a VF reset occurs. Previously the promiscuous mode settings were still there after the VF driver removal.
Quoted 5 lines
Signed-off-by Mariusz Stachura <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 267 ++++++++++++----- ---- 1 file changed, 157 insertions(+), 110 deletions(-)>
PATCH 8/12 i40evf: Validate the number of queues a PF sends
In reply to Alice MichaelFrom: Paul M Stillwell Jr <[email protected]>
A PF can send any number of queues to the VF and the VF may not be able to support that many. Check to see that the number of queues is less than or equal to the max number of queues the VF can have.
--- .../net/ethernet/intel/i40evf/i40evf_virtchnl.c | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+)
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c +32 -0
@@ -154,6 +154,32 @@ int i40evf_send_vf_config_msg(struct i40evf_adapter *adapter) }/** +* i40evf_validate_num_queues +* @adapter: adapter structure +* +* Validate that the number of queues the PF has sent in +* VIRTCHNL_OP_GET_VF_RESOURCES is not larger than the VF can handle. +**/ +static void i40evf_validate_num_queues (struct i40evf_adapter *adapter) +{ +if (adapter->vf_res->num_queue_pairs >I40EVF_MAX_REQ_QUEUES ) { +struct virtchnl_vsi_resource *vsi_res; +int i; + +dev_info (&adapter->pdev->dev,"Received %d queues, but can only have a max of %d\n" , + adapter->vf_res->num_queue_pairs, +I40EVF_MAX_REQ_QUEUES ); +dev_info (&adapter->pdev->dev,"Fixing by reducing queues to %d\n" , +I40EVF_MAX_REQ_QUEUES ); + adapter->vf_res->num_queue_pairs =I40EVF_MAX_REQ_QUEUES ; +for (i =0 ; i < adapter->vf_res->num_vsis; i++) { + vsi_res = &adapter->vf_res->vsi_res[i]; + vsi_res->num_queue_pairs =I40EVF_MAX_REQ_QUEUES ; + } + } +} + +/** * i40evf_get_vf_config * @adapter: private adapter structure *
@@ -195,6 +221,11 @@ int i40evf_get_vf_config(struct i40evf_adapter *adapter) err = (i40e_status )le32_to_cpu (event.desc.cookie_low);memcpy (adapter->vf_res, event.msg_buf,min (event.msg_len, len)); +/* some PFs send more queues than we should have so validate that +* we aren't getting too many queues +*/ +if (!err) +i40evf_validate_num_queues (adapter);i40e_vf_parse_hw_config (hw, adapter->vf_res); out_alloc:kfree (event.msg_buf);
@@ -1329,6 +1360,7 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,I40E_MAX_VF_VSI * sizeof(struct virtchnl_vsi_resource);memcpy (adapter->vf_res, msg,min (msglen, len)); +i40evf_validate_num_queues (adapter);i40e_vf_parse_hw_config (&adapter->hw, adapter->vf_res);if (is_zero_ether_addr (adapter->hw.mac.addr)) {/* restore current mac address */
Signature · 1 line
2.9.5
Bowers
PATCH 8/12 i40evf: Validate the number of queues a PF sends
Quoted 16 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:12 AM
To: Michael, Alice <[email protected]>; intel-wired- lan at lists.osuosl.org
Cc: Stillwell Jr, Paul M <[email protected]>
Subject: [Intel-wired-lan] [next PATCH S95 08/12] i40evf: Validate the number of queues a PF sendsFrom: Paul M Stillwell Jr <[email protected]>
A PF can send any number of queues to the VF and the VF may not be able to support that many. Check to see that the number of queues is less than or equal to the max number of queues the VF can have.
Quoted 5 lines
Signed-off-by Paul M Stillwell Jr <[email protected]>--- .../net/ethernet/intel/i40evf/i40evf_virtchnl.c | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+)
PATCH 9/12 i40e: use correct length for strncpy
In reply to Alice MichaelFrom: Mitch Williams <[email protected]>
Caught by gcc 8. When we provide a length for strncpy, we should not include the terminating null. So we must tell it one less than the size of the destination buffer.
--- drivers/net/ethernet/intel/i40e/i40e_ptp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/i40e/i40e_ptp.c +2 -1
@@ -694,7 +694,8 @@ static long i40e_ptp_create_clock(struct i40e_pf *pf)if (!IS_ERR_OR_NULL (pf->ptp_clock))return 0 ; -strncpy (pf->ptp_caps.name, i40e_driver_name,sizeof (pf->ptp_caps.name)); +strncpy (pf->ptp_caps.name, i40e_driver_name, +sizeof (pf->ptp_caps.name) -1 ); pf->ptp_caps.owner =THIS_MODULE ; pf->ptp_caps.max_adj =999999999 ; pf->ptp_caps.n_ext_ts =0 ;
Signature · 1 line
2.9.5
PATCH 9/12 i40e: use correct length for strncpy
Quoted 16 lines · Alice Michael
From: Mitch Williams <[email protected]>
Caught by gcc 8. When we provide a length for strncpy, we should not include the terminating null. So we must tell it one less than the size of the destination buffer.
Signed-off-by Mitch Williams <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_ptp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/net/ethernet/intel/i40e/i40e_ptp.c +0
-0
drivers/net/ethernet/intel/i40e/i40e_ptp.c static long i40e_ptp_create_clock(struct i40e_pf *pf) · line 698
Quoted 6 lines
drivers/net/ethernet/intel/i40e/i40e_ptp.c +2
-1@@ -694,7 +694,8 @@ static long i40e_ptp_create_clock(struct i40e_pf *pf)if (!IS_ERR_OR_NULL (pf->ptp_clock))return 0 ; -strncpy (pf->ptp_caps.name, i40e_driver_name,sizeof (pf->ptp_caps.name)); +strncpy (pf->ptp_caps.name, i40e_driver_name, +sizeof (pf->ptp_caps.name) -1 );
Is there any need to be sure the rest of the name field is zero'd out? It looks like maybe not, not sure.
sln
Quoted 4 lines
drivers/net/ethernet/intel/i40e/i40e_ptp.c +0
-0pf->ptp_caps.owner =THIS_MODULE ; pf->ptp_caps.max_adj =999999999 ; pf->ptp_caps.n_ext_ts =0 ;
Bowers
PATCH 9/12 i40e: use correct length for strncpy
In reply to Alice MichaelQuoted 11 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:13 AM
To: Michael, Alice <[email protected]>; intel-wired-
lan at lists.osuosl.org
Subject: [Intel-wired-lan] [next PATCH S95 09/12] i40e: use correct length for strncpyFrom: Mitch Williams <[email protected]>
Quoted 8 lines
Caught by gcc 8. When we provide a length for strncpy, we should not include the terminating null. So we must tell it one less than the size of the destination buffer.
Signed-off-by Mitch Williams <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_ptp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
PATCH 10/12 i40evf: set IFF_UNICAST_FLT flag for the vf
In reply to Alice MichaelFrom: Lihong Yang <[email protected]>
Set IFF_UNICAST_FLT flag for the vf to prevent it from entering promiscuous mode when macvlan is added to the vf.
--- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/intel/i40evf/i40evf_main.c +2 -0
@@ -3358,6 +3358,8 @@ int i40evf_process_config(struct i40evf_adapter *adapter)if (vfres->vf_cap_flags &VIRTCHNL_VF_OFFLOAD_VLAN ) netdev->features |=NETIF_F_HW_VLAN_CTAG_FILTER ; + netdev->priv_flags |=IFF_UNICAST_FLT ; +/* Do not turn on offloads when they are requested to be turned off. * TSO needs minimum 576 bytes to work correctly. */
Signature · 1 line
2.9.5
Bowers
PATCH 10/12 i40evf: set IFF_UNICAST_FLT flag for the vf
Quoted 11 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:13 AM
To: Michael, Alice <[email protected]>; intel-wired- lan at lists.osuosl.org
Subject: [Intel-wired-lan] [next PATCH S95 10/12] i40evf: setIFF_UNICAST_FLTflag for the vfFrom: Lihong Yang <[email protected]>
Quoted 7 lines
Set
IFF_UNICAST_FLTflag for the vf to prevent it from entering promiscuous mode when macvlan is added to the vf.Signed-off-by Lihong Yang <[email protected]>--- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 ++ 1 file changed, 2 insertions(+)
PATCH 11/12 virtchnl: use u8 type for a field in the virtchnl_filter struct
In reply to Alice MichaelFrom: Harshitha Ramamurthy <[email protected]>
The virtchnl_filter struct has a field called field_flags. A previous commit mistakenly had the type to be a __u8. What we want is for the field to be an unsigned 8 bit value, so let's just use the existing kernel type u8 for that.
--- include/linux/avf/virtchnl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/avf/virtchnl.h +1 -1
@@ -575,7 +575,7 @@ struct virtchnl_filter {enum virtchnl_flow_type flow_type;enum virtchnl_action action;u32 action_meta; -__u8 field_flags; +u8 field_flags; };VIRTCHNL_CHECK_STRUCT_LEN (272 , virtchnl_filter);
Signature · 1 line
2.9.5
Bowers
PATCH 11/12 virtchnl: use u8 type for a field in the virtchnl_filter struct
Quoted 11 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:13 AM
To: Michael, Alice <[email protected]>; intel-wired-
lan at lists.osuosl.org
Subject: [Intel-wired-lan] [next PATCH S95 11/12] virtchnl: use u8 type for a field in thevirtchnl_filterstructFrom: Harshitha Ramamurthy <[email protected]>
Quoted 8 lines
The
virtchnl_filterstruct has a field calledfield_flags. A previous commit mistakenly had the type to be a__u8. What we want is for the field to be an unsigned 8 bit value, so let's just use the existing kernel type u8 for that.Signed-off-by Harshitha Ramamurthy <[email protected]>--- include/linux/avf/virtchnl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
PATCH 12/12 i40e: static analysis report from community
In reply to Alice MichaelFrom: Martyna Szapar <[email protected]>
Static analysis tools report a problem from original driver submission. Removing unnecessary check in condition.
--- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/i40e/i40e_main.c +1 -1
@@ -13129,7 +13129,7 @@ struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, u16 flags,for (vsi_idx =0 ; vsi_idx < pf->num_alloc_vsi; vsi_idx++)if (pf->vsi[vsi_idx] && pf->vsi[vsi_idx]->seid == vsi_seid)break ; -if (vsi_idx >= pf->num_alloc_vsi && vsi_seid !=0 ) { +if (vsi_idx == pf->num_alloc_vsi && vsi_seid !=0 ) {dev_info (&pf->pdev->dev,"vsi seid %d not found\n" , vsi_seid);return NULL ;
Signature · 1 line
2.9.5
Bowers
PATCH 12/12 i40e: static analysis report from community
Quoted 12 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:13 AM
To: Michael, Alice <[email protected]>; intel-wired-
lan at lists.osuosl.org
Cc: Szapar, Martyna <[email protected]>
Subject: [Intel-wired-lan] [next PATCH S95 12/12] i40e: static analysis report from communityFrom: Martyna Szapar <[email protected]>
Quoted 7 lines
Static analysis tools report a problem from original driver submission. Removing unnecessary check in condition.
Signed-off-by Martyna Szapar <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
PATCH 1/12 i40e: Fix VF's link state notification
In reply to Alice MichaelQuoted 6 lines · Alice Michael
From: Mariusz Stachura <[email protected]>
This patch moves saving old link status information after the call to
i40e_get_link_status(). Mentioned function updates both old and the new link info, so reading it before results in not notifying VF about the PF link state change.
I see that this is removing one instance of saving the current status, not moving it to somewhere else. I see that i40e_aq_get_link_info() is also doing the save, not i40e_get_link_status(). I don't see how this affects VF notification. Can you clean up this description and elaborate on how the VF notification is involved?
Quoted 11 lines
Signed-off-by Mariusz Stachura <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_main.c | 5 ----- 1 file changed, 5 deletions(-)drivers/net/ethernet/intel/i40e/i40e_main.c +0
-0
drivers/net/ethernet/intel/i40e/i40e_main.c static void i40e_link_event(struct i40e_pf *pf) · line 8451
Quoted 10 lines
drivers/net/ethernet/intel/i40e/i40e_main.c +0
-4@@ -8446,14 +8446,9 @@ static void i40e_link_event(struct i40e_pf *pf)i40e_status status;bool new_link, old_link; -/* save off old link status information */ - pf->hw.phy.link_info_old = pf->hw.phy.link_info; -/* set this to force the get_link_status call to refresh state */ pf->hw.phy.get_link_info = true; - old_link = (pf->hw.phy.link_info_old.link_info &I40E_AQ_LINK_UP );
Since link_info_old has not been refreshed yet by i40e_aq_get_link_info(), are you sure you are getting the old_link status that you want?
sln
Quoted 5 lines
drivers/net/ethernet/intel/i40e/i40e_main.c +0
-1- status =i40e_get_link_status (&pf->hw, &new_link);/* On success, disable temp link polling */
Bowers
PATCH 1/12 i40e: Fix VF's link state notification
In reply to Alice MichaelQuoted 16 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Monday, August 20, 2018 8:12 AM
To: Michael, Alice <[email protected]>; intel-wired-
lan at lists.osuosl.org
Subject: [Intel-wired-lan] [next PATCH S95 01/12] i40e: Fix VF's link state notificationFrom: Mariusz Stachura <[email protected]>
This patch moves saving old link status information after the call to
i40e_get_link_status(). Mentioned function updates both old and the new link info, so reading it before results in not notifying VF about the PF link state change.
Quoted 4 lines
Signed-off-by Mariusz Stachura <[email protected]>--- drivers/net/ethernet/intel/i40e/i40e_main.c | 5 ----- 1 file changed, 5 deletions(-)