Commit b8f64757 authored by Ioana Ciornei's avatar Ioana Ciornei Committed by Greg Kroah-Hartman
Browse files

staging: dpaa2-ethsw: ordered workqueue should be per ethsw



Create a different ordered workqueue per dpaa2-ethsw instance.  Without
this change, we overwrite the global queue and leak memory when probing
multiple instances of the driver.

Signed-off-by: default avatarIoana Ciornei <ioana.ciornei@nxp.com>
Link: https://lore.kernel.org/r/1573491058-24766-5-git-send-email-ioana.ciornei@nxp.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 910f3091
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -18,8 +18,6 @@

#include "ethsw.h"

static struct workqueue_struct *ethsw_owq;

/* Minimal supported DPSW version */
#define DPSW_MIN_VER_MAJOR		8
#define DPSW_MIN_VER_MINOR		1
@@ -1229,8 +1227,10 @@ static int port_switchdev_event(struct notifier_block *unused,
				unsigned long event, void *ptr)
{
	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
	struct ethsw_port_priv *port_priv = netdev_priv(dev);
	struct ethsw_switchdev_event_work *switchdev_work;
	struct switchdev_notifier_fdb_info *fdb_info = ptr;
	struct ethsw_core *ethsw = port_priv->ethsw_data;

	if (!ethsw_port_dev_check(dev))
		return NOTIFY_DONE;
@@ -1266,7 +1266,7 @@ static int port_switchdev_event(struct notifier_block *unused,
		return NOTIFY_DONE;
	}

	queue_work(ethsw_owq, &switchdev_work->work);
	queue_work(ethsw->workqueue, &switchdev_work->work);

	return NOTIFY_DONE;

@@ -1427,9 +1427,10 @@ static int ethsw_init(struct fsl_mc_device *sw_dev)
		}
	}

	ethsw_owq = alloc_ordered_workqueue("%s_ordered", WQ_MEM_RECLAIM,
					    "ethsw");
	if (!ethsw_owq) {
	ethsw->workqueue = alloc_ordered_workqueue("%s_%d_ordered",
						   WQ_MEM_RECLAIM, "ethsw",
						   ethsw->sw_attr.id);
	if (!ethsw->workqueue) {
		err = -ENOMEM;
		goto err_close;
	}
@@ -1441,7 +1442,7 @@ static int ethsw_init(struct fsl_mc_device *sw_dev)
	return 0;

err_destroy_ordered_workqueue:
	destroy_workqueue(ethsw_owq);
	destroy_workqueue(ethsw->workqueue);

err_close:
	dpsw_close(ethsw->mc_io, 0, ethsw->dpsw_handle);
@@ -1529,7 +1530,7 @@ static int ethsw_remove(struct fsl_mc_device *sw_dev)

	ethsw_teardown_irqs(sw_dev);

	destroy_workqueue(ethsw_owq);
	destroy_workqueue(ethsw->workqueue);

	dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle);

+1 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ struct ethsw_core {
	struct notifier_block		port_nb;
	struct notifier_block		port_switchdev_nb;
	struct notifier_block		port_switchdevb_nb;
	struct workqueue_struct		*workqueue;
};

#endif	/* __ETHSW_H */