lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 12 May 2014 21:56:00 +0200
From:	Veaceslav Falico <vfalico@...il.com>
To:	Ding Tianhong <dingtianhong@...wei.com>
Cc:	Jay Vosburgh <j.vosburgh@...il.com>,
	Andy Gospodarek <andy@...yhouse.net>,
	Netdev <netdev@...r.kernel.org>,
	"David S. Miller" <davem@...emloft.net>
Subject: Re: [PATCH net-next] bonding: alloc the structure ad_info
 dynamically in per slave

On Mon, May 12, 2014 at 03:08:43PM +0800, Ding Tianhong wrote:
>The struct ad_slave_info is very huge, and only be used for 802.3ad mode,
>so alloc the structure dynamically could save 356 Bits for every slave in
>non 802.3ad mode.

Seems ok, we'll just need to be sure to handle it nicely when we'll finally
be able to switch modes with slaves present.

Acked-by: Veaceslav Falico <vfalico@...il.com>

>
>Cc: Jay Vosburgh <j.vosburgh@...il.com>
>Cc: Veaceslav Falico <vfalico@...il.com>
>Cc: Andy Gospodarek <andy@...yhouse.net>
>Signed-off-by: Ding Tianhong <dingtianhong@...wei.com>
>---
> drivers/net/bonding/bond_3ad.c         | 54 +++++++++++++++++-----------------
> drivers/net/bonding/bond_main.c        | 42 ++++++++++++++++++++++----
> drivers/net/bonding/bond_netlink.c     |  2 +-
> drivers/net/bonding/bond_procfs.c      |  2 +-
> drivers/net/bonding/bond_sysfs_slave.c |  2 +-
> drivers/net/bonding/bonding.h          |  2 +-
> 6 files changed, 67 insertions(+), 37 deletions(-)
>
>diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
>index 9a0d61e..24faddd 100644
>--- a/drivers/net/bonding/bond_3ad.c
>+++ b/drivers/net/bonding/bond_3ad.c
>@@ -157,7 +157,7 @@ static inline struct aggregator *__get_first_agg(struct port *port)
>
> 	rcu_read_lock();
> 	first_slave = bond_first_slave_rcu(bond);
>-	agg = first_slave ? &(SLAVE_AD_INFO(first_slave).aggregator) : NULL;
>+	agg = first_slave ? &(SLAVE_AD_INFO(first_slave)->aggregator) : NULL;
> 	rcu_read_unlock();
>
> 	return agg;
>@@ -241,7 +241,7 @@ static inline int __check_agg_selection_timer(struct port *port)
>  */
> static inline void __get_state_machine_lock(struct port *port)
> {
>-	spin_lock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock));
>+	spin_lock_bh(&(SLAVE_AD_INFO(port->slave)->state_machine_lock));
> }
>
> /**
>@@ -250,7 +250,7 @@ static inline void __get_state_machine_lock(struct port *port)
>  */
> static inline void __release_state_machine_lock(struct port *port)
> {
>-	spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock));
>+	spin_unlock_bh(&(SLAVE_AD_INFO(port->slave)->state_machine_lock));
> }
>
> /**
>@@ -350,7 +350,7 @@ static u8 __get_duplex(struct port *port)
> static inline void __initialize_port_locks(struct slave *slave)
> {
> 	/* make sure it isn't called twice */
>-	spin_lock_init(&(SLAVE_AD_INFO(slave).state_machine_lock));
>+	spin_lock_init(&(SLAVE_AD_INFO(slave)->state_machine_lock));
> }
>
> /* Conversions */
>@@ -688,8 +688,8 @@ static struct aggregator *__get_active_agg(struct aggregator *aggregator)
> 	struct slave *slave;
>
> 	bond_for_each_slave_rcu(bond, slave, iter)
>-		if (SLAVE_AD_INFO(slave).aggregator.is_active)
>-			return &(SLAVE_AD_INFO(slave).aggregator);
>+		if (SLAVE_AD_INFO(slave)->aggregator.is_active)
>+			return &(SLAVE_AD_INFO(slave)->aggregator);
>
> 	return NULL;
> }
>@@ -1293,7 +1293,7 @@ static void ad_port_selection_logic(struct port *port)
> 	}
> 	/* search on all aggregators for a suitable aggregator for this port */
> 	bond_for_each_slave(bond, slave, iter) {
>-		aggregator = &(SLAVE_AD_INFO(slave).aggregator);
>+		aggregator = &(SLAVE_AD_INFO(slave)->aggregator);
>
> 		/* keep a free aggregator for later use(if needed) */
> 		if (!aggregator->lag_ports) {
>@@ -1504,7 +1504,7 @@ static void ad_agg_selection_logic(struct aggregator *agg)
> 	best = (active && agg_device_up(active)) ? active : NULL;
>
> 	bond_for_each_slave_rcu(bond, slave, iter) {
>-		agg = &(SLAVE_AD_INFO(slave).aggregator);
>+		agg = &(SLAVE_AD_INFO(slave)->aggregator);
>
> 		agg->is_active = 0;
>
>@@ -1549,7 +1549,7 @@ static void ad_agg_selection_logic(struct aggregator *agg)
> 			 best->slave ? best->slave->dev->name : "NULL");
>
> 		bond_for_each_slave_rcu(bond, slave, iter) {
>-			agg = &(SLAVE_AD_INFO(slave).aggregator);
>+			agg = &(SLAVE_AD_INFO(slave)->aggregator);
>
> 			pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
> 				 agg->aggregator_identifier, agg->num_of_ports,
>@@ -1840,16 +1840,16 @@ void bond_3ad_bind_slave(struct slave *slave)
> 	struct aggregator *aggregator;
>
> 	/* check that the slave has not been initialized yet. */
>-	if (SLAVE_AD_INFO(slave).port.slave != slave) {
>+	if (SLAVE_AD_INFO(slave)->port.slave != slave) {
>
> 		/* port initialization */
>-		port = &(SLAVE_AD_INFO(slave).port);
>+		port = &(SLAVE_AD_INFO(slave)->port);
>
> 		ad_initialize_port(port, bond->params.lacp_fast);
>
> 		__initialize_port_locks(slave);
> 		port->slave = slave;
>-		port->actor_port_number = SLAVE_AD_INFO(slave).id;
>+		port->actor_port_number = SLAVE_AD_INFO(slave)->id;
> 		/* key is determined according to the link speed, duplex and user key(which
> 		 * is yet not supported)
> 		 */
>@@ -1874,7 +1874,7 @@ void bond_3ad_bind_slave(struct slave *slave)
> 		__disable_port(port);
>
> 		/* aggregator initialization */
>-		aggregator = &(SLAVE_AD_INFO(slave).aggregator);
>+		aggregator = &(SLAVE_AD_INFO(slave)->aggregator);
>
> 		ad_initialize_agg(aggregator);
>
>@@ -1903,8 +1903,8 @@ void bond_3ad_unbind_slave(struct slave *slave)
> 	struct slave *slave_iter;
> 	struct list_head *iter;
>
>-	aggregator = &(SLAVE_AD_INFO(slave).aggregator);
>-	port = &(SLAVE_AD_INFO(slave).port);
>+	aggregator = &(SLAVE_AD_INFO(slave)->aggregator);
>+	port = &(SLAVE_AD_INFO(slave)->port);
>
> 	/* if slave is null, the whole port is not initialized */
> 	if (!port->slave) {
>@@ -1932,7 +1932,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
> 		    (aggregator->lag_ports->next_port_in_aggregator)) {
> 			/* find new aggregator for the related port(s) */
> 			bond_for_each_slave(bond, slave_iter, iter) {
>-				new_aggregator = &(SLAVE_AD_INFO(slave_iter).aggregator);
>+				new_aggregator = &(SLAVE_AD_INFO(slave_iter)->aggregator);
> 				/* if the new aggregator is empty, or it is
> 				 * connected to our port only
> 				 */
>@@ -2010,7 +2010,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
>
> 	/* find the aggregator that this port is connected to */
> 	bond_for_each_slave(bond, slave_iter, iter) {
>-		temp_aggregator = &(SLAVE_AD_INFO(slave_iter).aggregator);
>+		temp_aggregator = &(SLAVE_AD_INFO(slave_iter)->aggregator);
> 		prev_port = NULL;
> 		/* search the port in the aggregator's related ports */
> 		for (temp_port = temp_aggregator->lag_ports; temp_port;
>@@ -2076,7 +2076,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
> 	if (BOND_AD_INFO(bond).agg_select_timer &&
> 	    !(--BOND_AD_INFO(bond).agg_select_timer)) {
> 		slave = bond_first_slave_rcu(bond);
>-		port = slave ? &(SLAVE_AD_INFO(slave).port) : NULL;
>+		port = slave ? &(SLAVE_AD_INFO(slave)->port) : NULL;
>
> 		/* select the active aggregator for the bond */
> 		if (port) {
>@@ -2094,7 +2094,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
>
> 	/* for each port run the state machines */
> 	bond_for_each_slave_rcu(bond, slave, iter) {
>-		port = &(SLAVE_AD_INFO(slave).port);
>+		port = &(SLAVE_AD_INFO(slave)->port);
> 		if (!port->slave) {
> 			pr_warn_ratelimited("%s: Warning: Found an uninitialized port\n",
> 					    bond->dev->name);
>@@ -2155,7 +2155,7 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave,
>
> 	if (length >= sizeof(struct lacpdu)) {
>
>-		port = &(SLAVE_AD_INFO(slave).port);
>+		port = &(SLAVE_AD_INFO(slave)->port);
>
> 		if (!port->slave) {
> 			pr_warn_ratelimited("%s: Warning: port of slave %s is uninitialized\n",
>@@ -2212,7 +2212,7 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
> {
> 	struct port *port;
>
>-	port = &(SLAVE_AD_INFO(slave).port);
>+	port = &(SLAVE_AD_INFO(slave)->port);
>
> 	/* if slave is null, the whole port is not initialized */
> 	if (!port->slave) {
>@@ -2245,7 +2245,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
> {
> 	struct port *port;
>
>-	port = &(SLAVE_AD_INFO(slave).port);
>+	port = &(SLAVE_AD_INFO(slave)->port);
>
> 	/* if slave is null, the whole port is not initialized */
> 	if (!port->slave) {
>@@ -2279,7 +2279,7 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
> {
> 	struct port *port;
>
>-	port = &(SLAVE_AD_INFO(slave).port);
>+	port = &(SLAVE_AD_INFO(slave)->port);
>
> 	/* if slave is null, the whole port is not initialized */
> 	if (!port->slave) {
>@@ -2347,7 +2347,7 @@ int bond_3ad_set_carrier(struct bonding *bond)
> 		ret = 0;
> 		goto out;
> 	}
>-	active = __get_active_agg(&(SLAVE_AD_INFO(first_slave).aggregator));
>+	active = __get_active_agg(&(SLAVE_AD_INFO(first_slave)->aggregator));
> 	if (active) {
> 		/* are enough slaves available to consider link up? */
> 		if (active->num_of_ports < bond->params.min_links) {
>@@ -2384,7 +2384,7 @@ int __bond_3ad_get_active_agg_info(struct bonding *bond,
> 	struct port *port;
>
> 	bond_for_each_slave_rcu(bond, slave, iter) {
>-		port = &(SLAVE_AD_INFO(slave).port);
>+		port = &(SLAVE_AD_INFO(slave)->port);
> 		if (port->aggregator && port->aggregator->is_active) {
> 			aggregator = port->aggregator;
> 			break;
>@@ -2444,7 +2444,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
> 	first_ok_slave = NULL;
>
> 	bond_for_each_slave_rcu(bond, slave, iter) {
>-		agg = SLAVE_AD_INFO(slave).port.aggregator;
>+		agg = SLAVE_AD_INFO(slave)->port.aggregator;
> 		if (!agg || agg->aggregator_identifier != agg_id)
> 			continue;
>
>@@ -2522,7 +2522,7 @@ void bond_3ad_update_lacp_rate(struct bonding *bond)
>
> 	lacp_fast = bond->params.lacp_fast;
> 	bond_for_each_slave(bond, slave, iter) {
>-		port = &(SLAVE_AD_INFO(slave).port);
>+		port = &(SLAVE_AD_INFO(slave)->port);
> 		__get_state_machine_lock(port);
> 		if (lacp_fast)
> 			port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT;
>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>index 9d08e00..7f32a61 100644
>--- a/drivers/net/bonding/bond_main.c
>+++ b/drivers/net/bonding/bond_main.c
>@@ -1163,6 +1163,35 @@ static void bond_upper_dev_unlink(struct net_device *bond_dev,
> 	rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE, GFP_KERNEL);
> }
>
>+static struct slave *bond_alloc_slave(struct bonding *bond)
>+{
>+	struct slave *slave = NULL;
>+
>+	slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
>+	if (!slave)
>+		return NULL;
>+
>+	if (bond->params.mode == BOND_MODE_8023AD) {
>+		SLAVE_AD_INFO(slave) = kzalloc(sizeof(struct ad_slave_info),
>+					       GFP_KERNEL);
>+		if (!SLAVE_AD_INFO(slave)) {
>+			kfree(slave);
>+			return NULL;
>+		}
>+	}
>+	return slave;
>+}
>+
>+static void bond_free_slave(struct slave *slave)
>+{
>+	struct bonding *bond = bond_get_bond_by_slave(slave);
>+
>+	if (bond->params.mode == BOND_MODE_8023AD)
>+		kfree(SLAVE_AD_INFO(slave));
>+
>+	kfree(slave);
>+}
>+
> /* enslave device <slave> to bond device <master> */
> int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
> {
>@@ -1290,11 +1319,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
> 	    bond->dev->addr_assign_type == NET_ADDR_RANDOM)
> 		bond_set_dev_addr(bond->dev, slave_dev);
>
>-	new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
>+	new_slave = bond_alloc_slave(bond);
> 	if (!new_slave) {
> 		res = -ENOMEM;
> 		goto err_undo_flags;
> 	}
>+
> 	/*
> 	 * Set the new_slave's queue_id to be zero.  Queue ID mapping
> 	 * is set via sysfs or module option if desired.
>@@ -1471,14 +1501,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
> 		bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW);
> 		/* if this is the first slave */
> 		if (!prev_slave) {
>-			SLAVE_AD_INFO(new_slave).id = 1;
>+			SLAVE_AD_INFO(new_slave)->id = 1;
> 			/* Initialize AD with the number of times that the AD timer is called in 1 second
> 			 * can be called only after the mac address of the bond is set
> 			 */
> 			bond_3ad_initialize(bond, 1000/AD_TIMER_INTERVAL);
> 		} else {
>-			SLAVE_AD_INFO(new_slave).id =
>-				SLAVE_AD_INFO(prev_slave).id + 1;
>+			SLAVE_AD_INFO(new_slave)->id =
>+				SLAVE_AD_INFO(prev_slave)->id + 1;
> 		}
>
> 		bond_3ad_bind_slave(new_slave);
>@@ -1599,7 +1629,7 @@ err_restore_mtu:
> 	dev_set_mtu(slave_dev, new_slave->original_mtu);
>
> err_free:
>-	kfree(new_slave);
>+	bond_free_slave(new_slave);
>
> err_undo_flags:
> 	/* Enslave of first slave has failed and we need to fix master's mac */
>@@ -1786,7 +1816,7 @@ static int __bond_release_one(struct net_device *bond_dev,
>
> 	slave_dev->priv_flags &= ~IFF_BONDING;
>
>-	kfree(slave);
>+	bond_free_slave(slave);
>
> 	return 0;  /* deletion OK */
> }
>diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
>index f847e16..0d06e75 100644
>--- a/drivers/net/bonding/bond_netlink.c
>+++ b/drivers/net/bonding/bond_netlink.c
>@@ -59,7 +59,7 @@ static int bond_fill_slave_info(struct sk_buff *skb,
> 	if (slave->bond->params.mode == BOND_MODE_8023AD) {
> 		const struct aggregator *agg;
>
>-		agg = SLAVE_AD_INFO(slave).port.aggregator;
>+		agg = SLAVE_AD_INFO(slave)->port.aggregator;
> 		if (agg)
> 			if (nla_put_u16(skb, IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
> 					agg->aggregator_identifier))
>diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
>index 013fdd0..6a261c8 100644
>--- a/drivers/net/bonding/bond_procfs.c
>+++ b/drivers/net/bonding/bond_procfs.c
>@@ -190,7 +190,7 @@ static void bond_info_show_slave(struct seq_file *seq,
>
> 	if (bond->params.mode == BOND_MODE_8023AD) {
> 		const struct aggregator *agg
>-			= SLAVE_AD_INFO(slave).port.aggregator;
>+			= SLAVE_AD_INFO(slave)->port.aggregator;
>
> 		if (agg)
> 			seq_printf(seq, "Aggregator ID: %d\n",
>diff --git a/drivers/net/bonding/bond_sysfs_slave.c b/drivers/net/bonding/bond_sysfs_slave.c
>index 2e4eec5..89bc3b3 100644
>--- a/drivers/net/bonding/bond_sysfs_slave.c
>+++ b/drivers/net/bonding/bond_sysfs_slave.c
>@@ -70,7 +70,7 @@ static ssize_t ad_aggregator_id_show(struct slave *slave, char *buf)
> 	const struct aggregator *agg;
>
> 	if (slave->bond->params.mode == BOND_MODE_8023AD) {
>-		agg = SLAVE_AD_INFO(slave).port.aggregator;
>+		agg = SLAVE_AD_INFO(slave)->port.aggregator;
> 		if (agg)
> 			return sprintf(buf, "%d\n",
> 				       agg->aggregator_identifier);
>diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
>index c1c7c2f..c3f44eb 100644
>--- a/drivers/net/bonding/bonding.h
>+++ b/drivers/net/bonding/bonding.h
>@@ -205,7 +205,7 @@ struct slave {
> 	u32    speed;
> 	u16    queue_id;
> 	u8     perm_hwaddr[ETH_ALEN];
>-	struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
>+	struct ad_slave_info *ad_info;
> 	struct tlb_slave_info tlb_info;
> #ifdef CONFIG_NET_POLL_CONTROLLER
> 	struct netpoll *np;
>-- 
>1.8.0
>
>
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ