All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Safe tailq element removal in i40e driver
@ 2016-07-22 13:08 Pablo de Lara
  2016-07-22 13:08 ` [PATCH 1/2] eal: add tailq safe iterator macro Pablo de Lara
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Pablo de Lara @ 2016-07-22 13:08 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, Pablo de Lara

i40e driver was removing elements when iterating tailq lists 
with TAILQ_FOREACH macro, which is not safe.
Instead, TAILQ_FOREACH_SAFE macro is used when removing/freeing
these elements, which is defined in DPDK if it is not already
defined (in FreeBSD).

Pablo de Lara (2):
  eal: add tailq safe iterator macro
  net/i40e: avoid unsafe tailq element removal

 drivers/net/i40e/i40e_ethdev.c            | 12 +++++++-----
 lib/librte_eal/common/include/rte_tailq.h | 11 +++++++++++
 2 files changed, 18 insertions(+), 5 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] eal: add tailq safe iterator macro
  2016-07-22 13:08 [PATCH 0/2] Safe tailq element removal in i40e driver Pablo de Lara
@ 2016-07-22 13:08 ` Pablo de Lara
  2016-07-22 13:08 ` [PATCH 2/2] net/i40e: avoid unsafe tailq element removal Pablo de Lara
  2016-07-22 14:02 ` [PATCH v2 0/2] Safe tailq element removal in i40e driver Pablo de Lara
  2 siblings, 0 replies; 8+ messages in thread
From: Pablo de Lara @ 2016-07-22 13:08 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, Pablo de Lara

Removing/freeing elements elements within a TAILQ_FOREACH loop is not safe.
FreeBSD defines TAILQ_FOREACH_SAFE macro, which permits
these operations safely.
This patch defines this macro for Linux systems, where it is not defined.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 lib/librte_eal/common/include/rte_tailq.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_tailq.h b/lib/librte_eal/common/include/rte_tailq.h
index 4a686e6..cc3c0f1 100644
--- a/lib/librte_eal/common/include/rte_tailq.h
+++ b/lib/librte_eal/common/include/rte_tailq.h
@@ -155,6 +155,14 @@ void __attribute__((constructor, used)) tailqinitfn_ ##t(void) \
 		rte_panic("Cannot initialize tailq: %s\n", t.name); \
 }
 
+/* This macro permits both remove and free var within the loop safely.*/
+#ifndef TAILQ_FOREACH_SAFE
+#define TAILQ_FOREACH_SAFE(var, head, field, tvar)		\
+	for ((var) = TAILQ_FIRST((head));			\
+	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);	\
+	    (var) = (tvar))
+#endif
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] net/i40e: avoid unsafe tailq element removal
  2016-07-22 13:08 [PATCH 0/2] Safe tailq element removal in i40e driver Pablo de Lara
  2016-07-22 13:08 ` [PATCH 1/2] eal: add tailq safe iterator macro Pablo de Lara
@ 2016-07-22 13:08 ` Pablo de Lara
  2016-07-22 14:02 ` [PATCH v2 0/2] Safe tailq element removal in i40e driver Pablo de Lara
  2 siblings, 0 replies; 8+ messages in thread
From: Pablo de Lara @ 2016-07-22 13:08 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, Pablo de Lara

i40e driver was removing elements when iterating tailq lists
with TAILQ_FOREACH macro, which is not safe.
Instead, TAILQ_FOREACH_SAFE macro is used when removing/freeing
these elements.

Fixes: 4861cde46116 ("i40e: new poll mode driver")
Fixes: 440499cf5376 ("net/i40e: support floating VEB")

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 84c86aa..11a5804 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -31,7 +31,6 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <sys/queue.h>
 #include <stdio.h>
 #include <errno.h>
 #include <stdint.h>
@@ -51,6 +50,7 @@
 #include <rte_alarm.h>
 #include <rte_dev.h>
 #include <rte_eth_ctrl.h>
+#include <rte_tailq.h>
 
 #include "i40e_logs.h"
 #include "base/i40e_prototype.h"
@@ -4094,6 +4094,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_pf *pf;
 	struct i40e_hw *hw;
 	struct i40e_vsi_list *vsi_list;
+	void *temp;
 	int ret;
 	struct i40e_mac_filter *f;
 	uint16_t user_param = vsi->user_param;
@@ -4106,7 +4107,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 
 	/* VSI has child to attach, release child first */
 	if (vsi->veb) {
-		TAILQ_FOREACH(vsi_list, &vsi->veb->head, list) {
+		TAILQ_FOREACH_SAFE(vsi_list, &vsi->veb->head, list, temp) {
 			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
 				return -1;
 			TAILQ_REMOVE(&vsi->veb->head, vsi_list, list);
@@ -4115,7 +4116,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	}
 
 	if (vsi->floating_veb) {
-		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+		TAILQ_FOREACH_SAFE(vsi_list, &vsi->floating_veb->head, list, temp) {
 			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
 				return -1;
 			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
@@ -4124,7 +4125,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
-	TAILQ_FOREACH(f, &vsi->mac_list, next)
+	TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp)
 		rte_free(f);
 
 	if (vsi->type != I40E_VSI_MAIN &&
@@ -4682,6 +4683,7 @@ i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on)
 {
 	int i, num;
 	struct i40e_mac_filter *f;
+	void *temp;
 	struct i40e_mac_filter_info *mac_filter;
 	enum rte_mac_filter_type desired_filter;
 	int ret = I40E_SUCCESS;
@@ -4706,7 +4708,7 @@ i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on)
 	i = 0;
 
 	/* Remove all existing mac */
-	TAILQ_FOREACH(f, &vsi->mac_list, next) {
+	TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) {
 		mac_filter[i] = f->mac_info;
 		ret = i40e_vsi_delete_mac(vsi, &f->mac_info.mac_addr);
 		if (ret) {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 0/2] Safe tailq element removal in i40e driver
  2016-07-22 13:08 [PATCH 0/2] Safe tailq element removal in i40e driver Pablo de Lara
  2016-07-22 13:08 ` [PATCH 1/2] eal: add tailq safe iterator macro Pablo de Lara
  2016-07-22 13:08 ` [PATCH 2/2] net/i40e: avoid unsafe tailq element removal Pablo de Lara
@ 2016-07-22 14:02 ` Pablo de Lara
  2016-07-22 14:02   ` [PATCH v2 1/2] eal: add tailq safe iterator macro Pablo de Lara
                     ` (2 more replies)
  2 siblings, 3 replies; 8+ messages in thread
From: Pablo de Lara @ 2016-07-22 14:02 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, Pablo de Lara

i40e driver was removing elements when iterating tailq lists 
with TAILQ_FOREACH macro, which is not safe.
Instead, TAILQ_FOREACH_SAFE macro is used when removing/freeing
these elements, which is defined in DPDK if it is not already
defined (in FreeBSD).

Changes in v2:
- Modified second commit title

Pablo de Lara (2):
  eal: add tailq safe iterator macro
  net/i40e: fix unsafe tailq element removal

 drivers/net/i40e/i40e_ethdev.c            | 12 +++++++-----
 lib/librte_eal/common/include/rte_tailq.h |  8 ++++++++
 2 files changed, 15 insertions(+), 5 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/2] eal: add tailq safe iterator macro
  2016-07-22 14:02 ` [PATCH v2 0/2] Safe tailq element removal in i40e driver Pablo de Lara
@ 2016-07-22 14:02   ` Pablo de Lara
  2016-07-22 14:02   ` [PATCH v2 2/2] net/i40e: fix unsafe tailq element removal Pablo de Lara
  2016-07-22 16:23   ` [PATCH v2 0/2] Safe tailq element removal in i40e driver Thomas Monjalon
  2 siblings, 0 replies; 8+ messages in thread
From: Pablo de Lara @ 2016-07-22 14:02 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, Pablo de Lara

Removing/freeing elements elements within a TAILQ_FOREACH loop is not safe.
FreeBSD defines TAILQ_FOREACH_SAFE macro, which permits
these operations safely.
This patch defines this macro for Linux systems, where it is not defined.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 lib/librte_eal/common/include/rte_tailq.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_tailq.h b/lib/librte_eal/common/include/rte_tailq.h
index 4a686e6..cc3c0f1 100644
--- a/lib/librte_eal/common/include/rte_tailq.h
+++ b/lib/librte_eal/common/include/rte_tailq.h
@@ -155,6 +155,14 @@ void __attribute__((constructor, used)) tailqinitfn_ ##t(void) \
 		rte_panic("Cannot initialize tailq: %s\n", t.name); \
 }
 
+/* This macro permits both remove and free var within the loop safely.*/
+#ifndef TAILQ_FOREACH_SAFE
+#define TAILQ_FOREACH_SAFE(var, head, field, tvar)		\
+	for ((var) = TAILQ_FIRST((head));			\
+	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);	\
+	    (var) = (tvar))
+#endif
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/2] net/i40e: fix unsafe tailq element removal
  2016-07-22 14:02 ` [PATCH v2 0/2] Safe tailq element removal in i40e driver Pablo de Lara
  2016-07-22 14:02   ` [PATCH v2 1/2] eal: add tailq safe iterator macro Pablo de Lara
@ 2016-07-22 14:02   ` Pablo de Lara
  2016-07-22 14:56     ` Thomas Monjalon
  2016-07-22 16:23   ` [PATCH v2 0/2] Safe tailq element removal in i40e driver Thomas Monjalon
  2 siblings, 1 reply; 8+ messages in thread
From: Pablo de Lara @ 2016-07-22 14:02 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, Pablo de Lara

i40e driver was removing elements when iterating tailq lists
with TAILQ_FOREACH macro, which is not safe.
Instead, TAILQ_FOREACH_SAFE macro is used when removing/freeing
these elements.

Fixes: 4861cde46116 ("i40e: new poll mode driver")
Fixes: 440499cf5376 ("net/i40e: support floating VEB")

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 84c86aa..11a5804 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -31,7 +31,6 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <sys/queue.h>
 #include <stdio.h>
 #include <errno.h>
 #include <stdint.h>
@@ -51,6 +50,7 @@
 #include <rte_alarm.h>
 #include <rte_dev.h>
 #include <rte_eth_ctrl.h>
+#include <rte_tailq.h>
 
 #include "i40e_logs.h"
 #include "base/i40e_prototype.h"
@@ -4094,6 +4094,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_pf *pf;
 	struct i40e_hw *hw;
 	struct i40e_vsi_list *vsi_list;
+	void *temp;
 	int ret;
 	struct i40e_mac_filter *f;
 	uint16_t user_param = vsi->user_param;
@@ -4106,7 +4107,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 
 	/* VSI has child to attach, release child first */
 	if (vsi->veb) {
-		TAILQ_FOREACH(vsi_list, &vsi->veb->head, list) {
+		TAILQ_FOREACH_SAFE(vsi_list, &vsi->veb->head, list, temp) {
 			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
 				return -1;
 			TAILQ_REMOVE(&vsi->veb->head, vsi_list, list);
@@ -4115,7 +4116,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	}
 
 	if (vsi->floating_veb) {
-		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+		TAILQ_FOREACH_SAFE(vsi_list, &vsi->floating_veb->head, list, temp) {
 			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
 				return -1;
 			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
@@ -4124,7 +4125,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
-	TAILQ_FOREACH(f, &vsi->mac_list, next)
+	TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp)
 		rte_free(f);
 
 	if (vsi->type != I40E_VSI_MAIN &&
@@ -4682,6 +4683,7 @@ i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on)
 {
 	int i, num;
 	struct i40e_mac_filter *f;
+	void *temp;
 	struct i40e_mac_filter_info *mac_filter;
 	enum rte_mac_filter_type desired_filter;
 	int ret = I40E_SUCCESS;
@@ -4706,7 +4708,7 @@ i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on)
 	i = 0;
 
 	/* Remove all existing mac */
-	TAILQ_FOREACH(f, &vsi->mac_list, next) {
+	TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) {
 		mac_filter[i] = f->mac_info;
 		ret = i40e_vsi_delete_mac(vsi, &f->mac_info.mac_addr);
 		if (ret) {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/2] net/i40e: fix unsafe tailq element removal
  2016-07-22 14:02   ` [PATCH v2 2/2] net/i40e: fix unsafe tailq element removal Pablo de Lara
@ 2016-07-22 14:56     ` Thomas Monjalon
  0 siblings, 0 replies; 8+ messages in thread
From: Thomas Monjalon @ 2016-07-22 14:56 UTC (permalink / raw)
  To: Pablo de Lara; +Cc: dev, helin.zhang, sergio.gonzalez.monroy

2016-07-22 15:02, Pablo de Lara:
> i40e driver was removing elements when iterating tailq lists
> with TAILQ_FOREACH macro, which is not safe.
> Instead, TAILQ_FOREACH_SAFE macro is used when removing/freeing
> these elements.

Pablo,
Maybe we should add a note to explain that the bug of freeing
while iterating is seen since the memory is zeroed on free:
	ea0bddbd14e6 ("mem: zero out memory on free")

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/2] Safe tailq element removal in i40e driver
  2016-07-22 14:02 ` [PATCH v2 0/2] Safe tailq element removal in i40e driver Pablo de Lara
  2016-07-22 14:02   ` [PATCH v2 1/2] eal: add tailq safe iterator macro Pablo de Lara
  2016-07-22 14:02   ` [PATCH v2 2/2] net/i40e: fix unsafe tailq element removal Pablo de Lara
@ 2016-07-22 16:23   ` Thomas Monjalon
  2 siblings, 0 replies; 8+ messages in thread
From: Thomas Monjalon @ 2016-07-22 16:23 UTC (permalink / raw)
  To: Pablo de Lara; +Cc: dev, helin.zhang

2016-07-22 15:02, Pablo de Lara:
> i40e driver was removing elements when iterating tailq lists 
> with TAILQ_FOREACH macro, which is not safe.
> Instead, TAILQ_FOREACH_SAFE macro is used when removing/freeing
> these elements, which is defined in DPDK if it is not already
> defined (in FreeBSD).

Applied, thanks

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-07-22 16:23 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-22 13:08 [PATCH 0/2] Safe tailq element removal in i40e driver Pablo de Lara
2016-07-22 13:08 ` [PATCH 1/2] eal: add tailq safe iterator macro Pablo de Lara
2016-07-22 13:08 ` [PATCH 2/2] net/i40e: avoid unsafe tailq element removal Pablo de Lara
2016-07-22 14:02 ` [PATCH v2 0/2] Safe tailq element removal in i40e driver Pablo de Lara
2016-07-22 14:02   ` [PATCH v2 1/2] eal: add tailq safe iterator macro Pablo de Lara
2016-07-22 14:02   ` [PATCH v2 2/2] net/i40e: fix unsafe tailq element removal Pablo de Lara
2016-07-22 14:56     ` Thomas Monjalon
2016-07-22 16:23   ` [PATCH v2 0/2] Safe tailq element removal in i40e driver Thomas Monjalon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.