Skip to content

Commit

Permalink
bridge: Add hash elasticity/max sysfs entries
Browse files Browse the repository at this point in the history
This patch allows the user to control the hash elasticity/max
parameters.  The elasticity setting does not take effect until
the next new multicast group is added.  At which point it is
checked and if after rehashing it still can't be satisfied then
snooping will be disabled.

The max setting on the other hand takes effect immediately.  It
must be a power of two and cannot be set to a value less than the
current number of multicast group entries.  This is the only way
to shrink the multicast hash.

Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
herbertx authored and davem330 committed Feb 28, 2010
1 parent 561f110 commit b195167
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 0 deletions.
41 changes: 41 additions & 0 deletions net/bridge/br_multicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/igmp.h>
#include <linux/jhash.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/netdevice.h>
#include <linux/netfilter_bridge.h>
#include <linux/random.h>
Expand Down Expand Up @@ -1261,3 +1262,43 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val)

return err;
}

int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val)
{
int err = -ENOENT;
u32 old;

spin_lock(&br->multicast_lock);
if (!netif_running(br->dev))
goto unlock;

err = -EINVAL;
if (!is_power_of_2(val))
goto unlock;
if (br->mdb && val < br->mdb->size)
goto unlock;

err = 0;

old = br->hash_max;
br->hash_max = val;

if (br->mdb) {
if (br->mdb->old) {
err = -EEXIST;
rollback:
br->hash_max = old;
goto unlock;
}

err = br_mdb_rehash(&br->mdb, br->hash_max,
br->hash_elasticity);
if (err)
goto rollback;
}

unlock:
spin_unlock(&br->multicast_lock);

return err;
}
1 change: 1 addition & 0 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ extern int br_multicast_set_router(struct net_bridge *br, unsigned long val);
extern int br_multicast_set_port_router(struct net_bridge_port *p,
unsigned long val);
extern int br_multicast_toggle(struct net_bridge *br, unsigned long val);
extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
#else
static inline int br_multicast_rcv(struct net_bridge *br,
struct net_bridge_port *port,
Expand Down
39 changes: 39 additions & 0 deletions net/bridge/br_sysfs_br.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,43 @@ static ssize_t store_multicast_snooping(struct device *d,
}
static DEVICE_ATTR(multicast_snooping, S_IRUGO | S_IWUSR,
show_multicast_snooping, store_multicast_snooping);

static ssize_t show_hash_elasticity(struct device *d,
struct device_attribute *attr, char *buf)
{
struct net_bridge *br = to_bridge(d);
return sprintf(buf, "%u\n", br->hash_elasticity);
}

static int set_elasticity(struct net_bridge *br, unsigned long val)
{
br->hash_elasticity = val;
return 0;
}

static ssize_t store_hash_elasticity(struct device *d,
struct device_attribute *attr,
const char *buf, size_t len)
{
return store_bridge_parm(d, buf, len, set_elasticity);
}
static DEVICE_ATTR(hash_elasticity, S_IRUGO | S_IWUSR, show_hash_elasticity,
store_hash_elasticity);

static ssize_t show_hash_max(struct device *d, struct device_attribute *attr,
char *buf)
{
struct net_bridge *br = to_bridge(d);
return sprintf(buf, "%u\n", br->hash_max);
}

static ssize_t store_hash_max(struct device *d, struct device_attribute *attr,
const char *buf, size_t len)
{
return store_bridge_parm(d, buf, len, br_multicast_set_hash_max);
}
static DEVICE_ATTR(hash_max, S_IRUGO | S_IWUSR, show_hash_max,
store_hash_max);
#endif

static struct attribute *bridge_attrs[] = {
Expand All @@ -402,6 +439,8 @@ static struct attribute *bridge_attrs[] = {
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
&dev_attr_multicast_router.attr,
&dev_attr_multicast_snooping.attr,
&dev_attr_hash_elasticity.attr,
&dev_attr_hash_max.attr,
#endif
NULL
};
Expand Down

0 comments on commit b195167

Please sign in to comment.