[V2] ethdev: add dev configured flag

Message ID 1625544608-30590-1-git-send-email-lihuisong@huawei.com (mailing list archive)
State Superseded, archived
Delegated to: Andrew Rybchenko
Headers
Series [V2] ethdev: add dev configured flag |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/github-robot fail github build: failed
ci/Intel-compilation success Compilation OK
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-testing fail Testing issues
ci/iol-abi-testing warning Testing issues

Commit Message

lihuisong (C) July 6, 2021, 4:10 a.m. UTC
  Currently, if dev_configure is not called or fails to be called, users
can still call dev_start successfully. So it is necessary to have a flag
which indicates whether the device is configured, to control whether
dev_start can be called and eliminate dependency on user invocation order.

The flag stored in "struct rte_eth_dev_data" is more reasonable than
 "enum rte_eth_dev_state". "enum rte_eth_dev_state" is private to the
primary and secondary processes, and can be independently controlled.
However, the secondary process does not make resource allocations and
does not call dev_configure(). These are done by the primary process
and can be obtained or used by the secondary process. So this patch
adds a "dev_configured" flag in "rte_eth_dev_data", like "dev_started".

Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
v1 -> v2:
  - adjusting the description of patch.

---
 lib/ethdev/rte_ethdev.c      | 16 ++++++++++++++++
 lib/ethdev/rte_ethdev_core.h |  6 +++++-
 2 files changed, 21 insertions(+), 1 deletion(-)
  

Comments

Andrew Rybchenko July 6, 2021, 8:36 a.m. UTC | #1
@David, could you take a look at the ABI breakage warnings for
the patch. May we ignore it since ABI looks backward
compatible? Or should be marked as a minor change ABI
which is backward compatible with DPDK_21?

On 7/6/21 7:10 AM, Huisong Li wrote:
> Currently, if dev_configure is not called or fails to be called, users
> can still call dev_start successfully. So it is necessary to have a flag
> which indicates whether the device is configured, to control whether
> dev_start can be called and eliminate dependency on user invocation order.
> 
> The flag stored in "struct rte_eth_dev_data" is more reasonable than
>  "enum rte_eth_dev_state". "enum rte_eth_dev_state" is private to the
> primary and secondary processes, and can be independently controlled.
> However, the secondary process does not make resource allocations and
> does not call dev_configure(). These are done by the primary process
> and can be obtained or used by the secondary process. So this patch
> adds a "dev_configured" flag in "rte_eth_dev_data", like "dev_started".
> 
> Signed-off-by: Huisong Li <lihuisong@huawei.com>

Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

> ---
> v1 -> v2:
>   - adjusting the description of patch.
> 
> ---
>  lib/ethdev/rte_ethdev.c      | 16 ++++++++++++++++
>  lib/ethdev/rte_ethdev_core.h |  6 +++++-
>  2 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index c607eab..6540432 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -1356,6 +1356,13 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>  		return -EBUSY;
>  	}
>  
> +	/*
> +	 * Ensure that "dev_configured" is always 0 each time prepare to do
> +	 * dev_configure() to avoid any non-anticipated behaviour.
> +	 * And set to 1 when dev_configure() is executed successfully.
> +	 */
> +	dev->data->dev_configured = 0;
> +
>  	 /* Store original config, as rollback required on failure */
>  	memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf));
>  
> @@ -1606,6 +1613,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>  	}
>  
>  	rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0);
> +	dev->data->dev_configured = 1;
> +

I think it should be inserted before the trace, since tracing
is intentionally put close to return without any empty lines
in between.

>  	return 0;
>  reset_queues:
>  	eth_dev_rx_queue_config(dev, 0);
> @@ -1751,6 +1760,13 @@ rte_eth_dev_start(uint16_t port_id)
>  
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
>  
> +	if (dev->data->dev_configured == 0) {
> +		RTE_ETHDEV_LOG(INFO,
> +			"Device with port_id=%"PRIu16" is not configured.\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	if (dev->data->dev_started != 0) {
>  		RTE_ETHDEV_LOG(INFO,
>  			"Device with port_id=%"PRIu16" already started\n",
> diff --git a/lib/ethdev/rte_ethdev_core.h b/lib/ethdev/rte_ethdev_core.h
> index 4679d94..edf96de 100644
> --- a/lib/ethdev/rte_ethdev_core.h
> +++ b/lib/ethdev/rte_ethdev_core.h
> @@ -167,7 +167,11 @@ struct rte_eth_dev_data {
>  		scattered_rx : 1,  /**< RX of scattered packets is ON(1) / OFF(0) */
>  		all_multicast : 1, /**< RX all multicast mode ON(1) / OFF(0). */
>  		dev_started : 1,   /**< Device state: STARTED(1) / STOPPED(0). */
> -		lro         : 1;   /**< RX LRO is ON(1) / OFF(0) */
> +		lro         : 1,   /**< RX LRO is ON(1) / OFF(0) */
> +		dev_configured : 1;
> +		/**< Indicates whether the device is configured.
> +		 *   CONFIGURED(1) / NOT CONFIGURED(0).
> +		 */
>  	uint8_t rx_queue_state[RTE_MAX_QUEUES_PER_PORT];
>  		/**< Queues state: HAIRPIN(2) / STARTED(1) / STOPPED(0). */
>  	uint8_t tx_queue_state[RTE_MAX_QUEUES_PER_PORT];
>
  
Ananyev, Konstantin July 6, 2021, 5:49 p.m. UTC | #2
> Currently, if dev_configure is not called or fails to be called, users
> can still call dev_start successfully. So it is necessary to have a flag
> which indicates whether the device is configured, to control whether
> dev_start can be called and eliminate dependency on user invocation order.
> 
> The flag stored in "struct rte_eth_dev_data" is more reasonable than
>  "enum rte_eth_dev_state". "enum rte_eth_dev_state" is private to the
> primary and secondary processes, and can be independently controlled.
> However, the secondary process does not make resource allocations and
> does not call dev_configure(). These are done by the primary process
> and can be obtained or used by the secondary process. So this patch
> adds a "dev_configured" flag in "rte_eth_dev_data", like "dev_started".
> 
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> ---
> v1 -> v2:
>   - adjusting the description of patch.
> 
> ---
>  lib/ethdev/rte_ethdev.c      | 16 ++++++++++++++++
>  lib/ethdev/rte_ethdev_core.h |  6 +++++-
>  2 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index c607eab..6540432 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -1356,6 +1356,13 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>  		return -EBUSY;
>  	}
> 
> +	/*
> +	 * Ensure that "dev_configured" is always 0 each time prepare to do
> +	 * dev_configure() to avoid any non-anticipated behaviour.
> +	 * And set to 1 when dev_configure() is executed successfully.
> +	 */
> +	dev->data->dev_configured = 0;
> +
>  	 /* Store original config, as rollback required on failure */
>  	memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf));
> 
> @@ -1606,6 +1613,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>  	}
> 
>  	rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0);
> +	dev->data->dev_configured = 1;
> +
>  	return 0;
>  reset_queues:
>  	eth_dev_rx_queue_config(dev, 0);
> @@ -1751,6 +1760,13 @@ rte_eth_dev_start(uint16_t port_id)
> 
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
> 
> +	if (dev->data->dev_configured == 0) {
> +		RTE_ETHDEV_LOG(INFO,
> +			"Device with port_id=%"PRIu16" is not configured.\n",
> +			port_id);
> +		return -EINVAL;
> +	}
> +
>  	if (dev->data->dev_started != 0) {
>  		RTE_ETHDEV_LOG(INFO,
>  			"Device with port_id=%"PRIu16" already started\n",
> diff --git a/lib/ethdev/rte_ethdev_core.h b/lib/ethdev/rte_ethdev_core.h
> index 4679d94..edf96de 100644
> --- a/lib/ethdev/rte_ethdev_core.h
> +++ b/lib/ethdev/rte_ethdev_core.h
> @@ -167,7 +167,11 @@ struct rte_eth_dev_data {
>  		scattered_rx : 1,  /**< RX of scattered packets is ON(1) / OFF(0) */
>  		all_multicast : 1, /**< RX all multicast mode ON(1) / OFF(0). */
>  		dev_started : 1,   /**< Device state: STARTED(1) / STOPPED(0). */
> -		lro         : 1;   /**< RX LRO is ON(1) / OFF(0) */
> +		lro         : 1,   /**< RX LRO is ON(1) / OFF(0) */
> +		dev_configured : 1;
> +		/**< Indicates whether the device is configured.
> +		 *   CONFIGURED(1) / NOT CONFIGURED(0).
> +		 */
>  	uint8_t rx_queue_state[RTE_MAX_QUEUES_PER_PORT];
>  		/**< Queues state: HAIRPIN(2) / STARTED(1) / STOPPED(0). */
>  	uint8_t tx_queue_state[RTE_MAX_QUEUES_PER_PORT];
> --

Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

> 2.7.4
  
lihuisong (C) July 7, 2021, 2:55 a.m. UTC | #3
在 2021/7/6 16:36, Andrew Rybchenko 写道:
> @David, could you take a look at the ABI breakage warnings for
> the patch. May we ignore it since ABI looks backward
> compatible? Or should be marked as a minor change ABI
> which is backward compatible with DPDK_21?
>
> On 7/6/21 7:10 AM, Huisong Li wrote:
>> Currently, if dev_configure is not called or fails to be called, users
>> can still call dev_start successfully. So it is necessary to have a flag
>> which indicates whether the device is configured, to control whether
>> dev_start can be called and eliminate dependency on user invocation order.
>>
>> The flag stored in "struct rte_eth_dev_data" is more reasonable than
>>   "enum rte_eth_dev_state". "enum rte_eth_dev_state" is private to the
>> primary and secondary processes, and can be independently controlled.
>> However, the secondary process does not make resource allocations and
>> does not call dev_configure(). These are done by the primary process
>> and can be obtained or used by the secondary process. So this patch
>> adds a "dev_configured" flag in "rte_eth_dev_data", like "dev_started".
>>
>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>
>> ---
>> v1 -> v2:
>>    - adjusting the description of patch.
>>
>> ---
>>   lib/ethdev/rte_ethdev.c      | 16 ++++++++++++++++
>>   lib/ethdev/rte_ethdev_core.h |  6 +++++-
>>   2 files changed, 21 insertions(+), 1 deletion(-)
>>
>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>> index c607eab..6540432 100644
>> --- a/lib/ethdev/rte_ethdev.c
>> +++ b/lib/ethdev/rte_ethdev.c
>> @@ -1356,6 +1356,13 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>>   		return -EBUSY;
>>   	}
>>   
>> +	/*
>> +	 * Ensure that "dev_configured" is always 0 each time prepare to do
>> +	 * dev_configure() to avoid any non-anticipated behaviour.
>> +	 * And set to 1 when dev_configure() is executed successfully.
>> +	 */
>> +	dev->data->dev_configured = 0;
>> +
>>   	 /* Store original config, as rollback required on failure */
>>   	memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf));
>>   
>> @@ -1606,6 +1613,8 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
>>   	}
>>   
>>   	rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0);
>> +	dev->data->dev_configured = 1;
>> +
> I think it should be inserted before the trace, since tracing
> is intentionally put close to return without any empty lines
> in between.
All right. Do I need to send a patch V3?
>>   	return 0;
>>   reset_queues:
>>   	eth_dev_rx_queue_config(dev, 0);
>> @@ -1751,6 +1760,13 @@ rte_eth_dev_start(uint16_t port_id)
>>   
>>   	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
>>   
>> +	if (dev->data->dev_configured == 0) {
>> +		RTE_ETHDEV_LOG(INFO,
>> +			"Device with port_id=%"PRIu16" is not configured.\n",
>> +			port_id);
>> +		return -EINVAL;
>> +	}
>> +
>>   	if (dev->data->dev_started != 0) {
>>   		RTE_ETHDEV_LOG(INFO,
>>   			"Device with port_id=%"PRIu16" already started\n",
>> diff --git a/lib/ethdev/rte_ethdev_core.h b/lib/ethdev/rte_ethdev_core.h
>> index 4679d94..edf96de 100644
>> --- a/lib/ethdev/rte_ethdev_core.h
>> +++ b/lib/ethdev/rte_ethdev_core.h
>> @@ -167,7 +167,11 @@ struct rte_eth_dev_data {
>>   		scattered_rx : 1,  /**< RX of scattered packets is ON(1) / OFF(0) */
>>   		all_multicast : 1, /**< RX all multicast mode ON(1) / OFF(0). */
>>   		dev_started : 1,   /**< Device state: STARTED(1) / STOPPED(0). */
>> -		lro         : 1;   /**< RX LRO is ON(1) / OFF(0) */
>> +		lro         : 1,   /**< RX LRO is ON(1) / OFF(0) */
>> +		dev_configured : 1;
>> +		/**< Indicates whether the device is configured.
>> +		 *   CONFIGURED(1) / NOT CONFIGURED(0).
>> +		 */
>>   	uint8_t rx_queue_state[RTE_MAX_QUEUES_PER_PORT];
>>   		/**< Queues state: HAIRPIN(2) / STARTED(1) / STOPPED(0). */
>>   	uint8_t tx_queue_state[RTE_MAX_QUEUES_PER_PORT];
>>
> .
  
David Marchand July 7, 2021, 7:39 a.m. UTC | #4
On Tue, Jul 6, 2021 at 10:36 AM Andrew Rybchenko
<andrew.rybchenko@oktetlabs.ru> wrote:
>
> @David, could you take a look at the ABI breakage warnings for
> the patch. May we ignore it since ABI looks backward
> compatible? Or should be marked as a minor change ABI
> which is backward compatible with DPDK_21?

The whole eth_dev_shared_data area has always been reset to 0 at the
first port allocation in a dpdk application life.
Subsequent calls to rte_eth_dev_release_port() reset every port
eth_dev->data to 0.

This bit flag is added in a hole of the structure, and it is
set/manipulated internally of ethdev.

So unless the application was doing something nasty like highjacking
this empty hole in the structure, I see no problem with the change wrt
ABI.


I wonder if libabigail is too strict on this report.
Or maybe there is some extreme consideration on what a compiler could
do about this hole...
Dodji?


For now, we can waive the warning.
I'll look into the exception rule to add.
  
Andrew Rybchenko July 7, 2021, 8:23 a.m. UTC | #5
On 7/7/21 10:39 AM, David Marchand wrote:
> On Tue, Jul 6, 2021 at 10:36 AM Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru> wrote:
>>
>> @David, could you take a look at the ABI breakage warnings for
>> the patch. May we ignore it since ABI looks backward
>> compatible? Or should be marked as a minor change ABI
>> which is backward compatible with DPDK_21?
> 
> The whole eth_dev_shared_data area has always been reset to 0 at the
> first port allocation in a dpdk application life.
> Subsequent calls to rte_eth_dev_release_port() reset every port
> eth_dev->data to 0.
> 
> This bit flag is added in a hole of the structure, and it is
> set/manipulated internally of ethdev.
> 
> So unless the application was doing something nasty like highjacking
> this empty hole in the structure, I see no problem with the change wrt
> ABI.
> 
> 
> I wonder if libabigail is too strict on this report.
> Or maybe there is some extreme consideration on what a compiler could
> do about this hole...

I was wondering if it could be any specifics related to big-
little endian vs bit fields placement, but throw the idea
away...

> Dodji?
> 
> 
> For now, we can waive the warning.
> I'll look into the exception rule to add.

Thanks a lot. I'll hold on the patch for now.
  
Andrew Rybchenko July 7, 2021, 8:25 a.m. UTC | #6
On 7/7/21 5:55 AM, Huisong Li wrote:
> 
> 在 2021/7/6 16:36, Andrew Rybchenko 写道:
>> @David, could you take a look at the ABI breakage warnings for
>> the patch. May we ignore it since ABI looks backward
>> compatible? Or should be marked as a minor change ABI
>> which is backward compatible with DPDK_21?
>>
>> On 7/6/21 7:10 AM, Huisong Li wrote:
>>> Currently, if dev_configure is not called or fails to be called, users
>>> can still call dev_start successfully. So it is necessary to have a flag
>>> which indicates whether the device is configured, to control whether
>>> dev_start can be called and eliminate dependency on user invocation
>>> order.
>>>
>>> The flag stored in "struct rte_eth_dev_data" is more reasonable than
>>>   "enum rte_eth_dev_state". "enum rte_eth_dev_state" is private to the
>>> primary and secondary processes, and can be independently controlled.
>>> However, the secondary process does not make resource allocations and
>>> does not call dev_configure(). These are done by the primary process
>>> and can be obtained or used by the secondary process. So this patch
>>> adds a "dev_configured" flag in "rte_eth_dev_data", like "dev_started".
>>>
>>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>
>>> ---
>>> v1 -> v2:
>>>    - adjusting the description of patch.
>>>
>>> ---
>>>   lib/ethdev/rte_ethdev.c      | 16 ++++++++++++++++
>>>   lib/ethdev/rte_ethdev_core.h |  6 +++++-
>>>   2 files changed, 21 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>>> index c607eab..6540432 100644
>>> --- a/lib/ethdev/rte_ethdev.c
>>> +++ b/lib/ethdev/rte_ethdev.c
>>> @@ -1356,6 +1356,13 @@ rte_eth_dev_configure(uint16_t port_id,
>>> uint16_t nb_rx_q, uint16_t nb_tx_q,
>>>           return -EBUSY;
>>>       }
>>>   +    /*
>>> +     * Ensure that "dev_configured" is always 0 each time prepare to do
>>> +     * dev_configure() to avoid any non-anticipated behaviour.
>>> +     * And set to 1 when dev_configure() is executed successfully.
>>> +     */
>>> +    dev->data->dev_configured = 0;
>>> +
>>>        /* Store original config, as rollback required on failure */
>>>       memcpy(&orig_conf, &dev->data->dev_conf,
>>> sizeof(dev->data->dev_conf));
>>>   @@ -1606,6 +1613,8 @@ rte_eth_dev_configure(uint16_t port_id,
>>> uint16_t nb_rx_q, uint16_t nb_tx_q,
>>>       }
>>>         rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q,
>>> dev_conf, 0);
>>> +    dev->data->dev_configured = 1;
>>> +
>> I think it should be inserted before the trace, since tracing
>> is intentionally put close to return without any empty lines
>> in between.
> All right. Do I need to send a patch V3?

Since the patch is waiting for resolution for ABI warning,
please, send v3 with my Reviewed-by and ack from Konstantin.
It will be a bit easier to apply when it is OK to do it.
  
lihuisong (C) July 7, 2021, 9:26 a.m. UTC | #7
在 2021/7/7 16:25, Andrew Rybchenko 写道:
> On 7/7/21 5:55 AM, Huisong Li wrote:
>> 在 2021/7/6 16:36, Andrew Rybchenko 写道:
>>> @David, could you take a look at the ABI breakage warnings for
>>> the patch. May we ignore it since ABI looks backward
>>> compatible? Or should be marked as a minor change ABI
>>> which is backward compatible with DPDK_21?
>>>
>>> On 7/6/21 7:10 AM, Huisong Li wrote:
>>>> Currently, if dev_configure is not called or fails to be called, users
>>>> can still call dev_start successfully. So it is necessary to have a flag
>>>> which indicates whether the device is configured, to control whether
>>>> dev_start can be called and eliminate dependency on user invocation
>>>> order.
>>>>
>>>> The flag stored in "struct rte_eth_dev_data" is more reasonable than
>>>>    "enum rte_eth_dev_state". "enum rte_eth_dev_state" is private to the
>>>> primary and secondary processes, and can be independently controlled.
>>>> However, the secondary process does not make resource allocations and
>>>> does not call dev_configure(). These are done by the primary process
>>>> and can be obtained or used by the secondary process. So this patch
>>>> adds a "dev_configured" flag in "rte_eth_dev_data", like "dev_started".
>>>>
>>>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
>>> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>>>
>>>> ---
>>>> v1 -> v2:
>>>>     - adjusting the description of patch.
>>>>
>>>> ---
>>>>    lib/ethdev/rte_ethdev.c      | 16 ++++++++++++++++
>>>>    lib/ethdev/rte_ethdev_core.h |  6 +++++-
>>>>    2 files changed, 21 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
>>>> index c607eab..6540432 100644
>>>> --- a/lib/ethdev/rte_ethdev.c
>>>> +++ b/lib/ethdev/rte_ethdev.c
>>>> @@ -1356,6 +1356,13 @@ rte_eth_dev_configure(uint16_t port_id,
>>>> uint16_t nb_rx_q, uint16_t nb_tx_q,
>>>>            return -EBUSY;
>>>>        }
>>>>    +    /*
>>>> +     * Ensure that "dev_configured" is always 0 each time prepare to do
>>>> +     * dev_configure() to avoid any non-anticipated behaviour.
>>>> +     * And set to 1 when dev_configure() is executed successfully.
>>>> +     */
>>>> +    dev->data->dev_configured = 0;
>>>> +
>>>>         /* Store original config, as rollback required on failure */
>>>>        memcpy(&orig_conf, &dev->data->dev_conf,
>>>> sizeof(dev->data->dev_conf));
>>>>    @@ -1606,6 +1613,8 @@ rte_eth_dev_configure(uint16_t port_id,
>>>> uint16_t nb_rx_q, uint16_t nb_tx_q,
>>>>        }
>>>>          rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q,
>>>> dev_conf, 0);
>>>> +    dev->data->dev_configured = 1;
>>>> +
>>> I think it should be inserted before the trace, since tracing
>>> is intentionally put close to return without any empty lines
>>> in between.
>> All right. Do I need to send a patch V3?
> Since the patch is waiting for resolution for ABI warning,
> please, send v3 with my Reviewed-by and ack from Konstantin.
> It will be a bit easier to apply when it is OK to do it.
> .
ok. I will send patch V3.
  
David Marchand July 7, 2021, 9:36 a.m. UTC | #8
On Wed, Jul 7, 2021 at 10:23 AM Andrew Rybchenko
<andrew.rybchenko@oktetlabs.ru> wrote:
>
> On 7/7/21 10:39 AM, David Marchand wrote:
> > On Tue, Jul 6, 2021 at 10:36 AM Andrew Rybchenko
> > <andrew.rybchenko@oktetlabs.ru> wrote:
> >>
> >> @David, could you take a look at the ABI breakage warnings for
> >> the patch. May we ignore it since ABI looks backward
> >> compatible? Or should be marked as a minor change ABI
> >> which is backward compatible with DPDK_21?
> >
> > The whole eth_dev_shared_data area has always been reset to 0 at the
> > first port allocation in a dpdk application life.
> > Subsequent calls to rte_eth_dev_release_port() reset every port
> > eth_dev->data to 0.
> >
> > This bit flag is added in a hole of the structure, and it is
> > set/manipulated internally of ethdev.
> >
> > So unless the application was doing something nasty like highjacking
> > this empty hole in the structure, I see no problem with the change wrt
> > ABI.
> >
> >
> > I wonder if libabigail is too strict on this report.
> > Or maybe there is some extreme consideration on what a compiler could
> > do about this hole...
>
> I was wondering if it could be any specifics related to big-
> little endian vs bit fields placement, but throw the idea
> away...

After some discussion offlist with (fairly busy ;-)) Dodji, the report
here is a good warning.

But it looks we have an issue with libabigail not properly computing
bitfields offsets.
I just opened a bz for tracking
https://sourceware.org/bugzilla/show_bug.cgi?id=28060

This is problematic, as the following rule does not work:

+; Ignore bitfields added in rte_eth_dev_data hole
+[suppress_type]
+        name = rte_eth_dev_data
+        has_data_member_inserted_between = {offset_after(lro),
offset_of(rx_queue_state)}

On the other hand, a (wrong) rule with "has_data_member_inserted_at =
2" (2 being the wrong offset you can read in abidiff output) works.

This might force us to waive all changes to rte_eth_dev_data... not
that I am happy about it.
  
Thomas Monjalon July 7, 2021, 9:59 a.m. UTC | #9
07/07/2021 11:36, David Marchand:
> On Wed, Jul 7, 2021 at 10:23 AM Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru> wrote:
> >
> > On 7/7/21 10:39 AM, David Marchand wrote:
> > > On Tue, Jul 6, 2021 at 10:36 AM Andrew Rybchenko
> > > <andrew.rybchenko@oktetlabs.ru> wrote:
> > >>
> > >> @David, could you take a look at the ABI breakage warnings for
> > >> the patch. May we ignore it since ABI looks backward
> > >> compatible? Or should be marked as a minor change ABI
> > >> which is backward compatible with DPDK_21?
> > >
> > > The whole eth_dev_shared_data area has always been reset to 0 at the
> > > first port allocation in a dpdk application life.
> > > Subsequent calls to rte_eth_dev_release_port() reset every port
> > > eth_dev->data to 0.
> > >
> > > This bit flag is added in a hole of the structure, and it is
> > > set/manipulated internally of ethdev.
> > >
> > > So unless the application was doing something nasty like highjacking
> > > this empty hole in the structure, I see no problem with the change wrt
> > > ABI.
> > >
> > >
> > > I wonder if libabigail is too strict on this report.
> > > Or maybe there is some extreme consideration on what a compiler could
> > > do about this hole...
> >
> > I was wondering if it could be any specifics related to big-
> > little endian vs bit fields placement, but throw the idea
> > away...
> 
> After some discussion offlist with (fairly busy ;-)) Dodji, the report
> here is a good warning.
> 
> But it looks we have an issue with libabigail not properly computing
> bitfields offsets.
> I just opened a bz for tracking
> https://sourceware.org/bugzilla/show_bug.cgi?id=28060
> 
> This is problematic, as the following rule does not work:
> 
> +; Ignore bitfields added in rte_eth_dev_data hole
> +[suppress_type]
> +        name = rte_eth_dev_data
> +        has_data_member_inserted_between = {offset_after(lro),
> offset_of(rx_queue_state)}
> 
> On the other hand, a (wrong) rule with "has_data_member_inserted_at =
> 2" (2 being the wrong offset you can read in abidiff output) works.
> 
> This might force us to waive all changes to rte_eth_dev_data... not
> that I am happy about it.

We are not going to do other changes until 21.11, so it could be fine.
  
David Marchand July 7, 2021, 10:40 a.m. UTC | #10
On Wed, Jul 7, 2021 at 11:59 AM Thomas Monjalon <thomas@monjalon.net> wrote:
> > This is problematic, as the following rule does not work:
> >
> > +; Ignore bitfields added in rte_eth_dev_data hole
> > +[suppress_type]
> > +        name = rte_eth_dev_data
> > +        has_data_member_inserted_between = {offset_after(lro),
> > offset_of(rx_queue_state)}
> >
> > On the other hand, a (wrong) rule with "has_data_member_inserted_at =
> > 2" (2 being the wrong offset you can read in abidiff output) works.
> >
> > This might force us to waive all changes to rte_eth_dev_data... not
> > that I am happy about it.
>
> We are not going to do other changes until 21.11, so it could be fine.

Ok, example of a global exception for the structure:

+; Ignore all changes to rte_eth_dev_data
+; Note: we only cared about dev_configured bit addition, but libabigail
+; seems to wrongly compute bitfields offset.
+; https://sourceware.org/bugzilla/show_bug.cgi?id=28060
+[suppress_type]
+        name = rte_eth_dev_data
  
Thomas Monjalon July 7, 2021, 10:57 a.m. UTC | #11
07/07/2021 12:40, David Marchand:
> On Wed, Jul 7, 2021 at 11:59 AM Thomas Monjalon <thomas@monjalon.net> wrote:
> > > This is problematic, as the following rule does not work:
> > >
> > > +; Ignore bitfields added in rte_eth_dev_data hole
> > > +[suppress_type]
> > > +        name = rte_eth_dev_data
> > > +        has_data_member_inserted_between = {offset_after(lro),
> > > offset_of(rx_queue_state)}
> > >
> > > On the other hand, a (wrong) rule with "has_data_member_inserted_at =
> > > 2" (2 being the wrong offset you can read in abidiff output) works.
> > >
> > > This might force us to waive all changes to rte_eth_dev_data... not
> > > that I am happy about it.
> >
> > We are not going to do other changes until 21.11, so it could be fine.
> 
> Ok, example of a global exception for the structure:
> 
> +; Ignore all changes to rte_eth_dev_data
> +; Note: we only cared about dev_configured bit addition, but libabigail
> +; seems to wrongly compute bitfields offset.
> +; https://sourceware.org/bugzilla/show_bug.cgi?id=28060
> +[suppress_type]
> +        name = rte_eth_dev_data

OK for me. Thanks for managing this issue.
  

Patch

diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index c607eab..6540432 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -1356,6 +1356,13 @@  rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 		return -EBUSY;
 	}
 
+	/*
+	 * Ensure that "dev_configured" is always 0 each time prepare to do
+	 * dev_configure() to avoid any non-anticipated behaviour.
+	 * And set to 1 when dev_configure() is executed successfully.
+	 */
+	dev->data->dev_configured = 0;
+
 	 /* Store original config, as rollback required on failure */
 	memcpy(&orig_conf, &dev->data->dev_conf, sizeof(dev->data->dev_conf));
 
@@ -1606,6 +1613,8 @@  rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
 	}
 
 	rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, 0);
+	dev->data->dev_configured = 1;
+
 	return 0;
 reset_queues:
 	eth_dev_rx_queue_config(dev, 0);
@@ -1751,6 +1760,13 @@  rte_eth_dev_start(uint16_t port_id)
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
 
+	if (dev->data->dev_configured == 0) {
+		RTE_ETHDEV_LOG(INFO,
+			"Device with port_id=%"PRIu16" is not configured.\n",
+			port_id);
+		return -EINVAL;
+	}
+
 	if (dev->data->dev_started != 0) {
 		RTE_ETHDEV_LOG(INFO,
 			"Device with port_id=%"PRIu16" already started\n",
diff --git a/lib/ethdev/rte_ethdev_core.h b/lib/ethdev/rte_ethdev_core.h
index 4679d94..edf96de 100644
--- a/lib/ethdev/rte_ethdev_core.h
+++ b/lib/ethdev/rte_ethdev_core.h
@@ -167,7 +167,11 @@  struct rte_eth_dev_data {
 		scattered_rx : 1,  /**< RX of scattered packets is ON(1) / OFF(0) */
 		all_multicast : 1, /**< RX all multicast mode ON(1) / OFF(0). */
 		dev_started : 1,   /**< Device state: STARTED(1) / STOPPED(0). */
-		lro         : 1;   /**< RX LRO is ON(1) / OFF(0) */
+		lro         : 1,   /**< RX LRO is ON(1) / OFF(0) */
+		dev_configured : 1;
+		/**< Indicates whether the device is configured.
+		 *   CONFIGURED(1) / NOT CONFIGURED(0).
+		 */
 	uint8_t rx_queue_state[RTE_MAX_QUEUES_PER_PORT];
 		/**< Queues state: HAIRPIN(2) / STARTED(1) / STOPPED(0). */
 	uint8_t tx_queue_state[RTE_MAX_QUEUES_PER_PORT];