Commit 520372a5 authored by Stephen Hemminger's avatar Stephen Hemminger

[BRIDGE]: Bridge confuses kernel user HZ.

parent 6eb563a4
...@@ -19,6 +19,21 @@ ...@@ -19,6 +19,21 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "br_private.h" #include "br_private.h"
/* Report time remaining in user HZ for compatibility. */
static inline unsigned long timer_residue(const struct br_timer *timer)
{
return timer->running
? ((jiffies - timer->expires) * USER_HZ)/HZ
: 0;
}
/* Convert API times in USER_HZ to kernel */
static inline unsigned long user_to_ticks(unsigned long utick)
{
return (utick * HZ) / USER_HZ;
}
static int br_ioctl_device(struct net_bridge *br, static int br_ioctl_device(struct net_bridge *br,
unsigned int cmd, unsigned int cmd,
unsigned long arg0, unsigned long arg0,
...@@ -70,10 +85,10 @@ static int br_ioctl_device(struct net_bridge *br, ...@@ -70,10 +85,10 @@ static int br_ioctl_device(struct net_bridge *br,
b.stp_enabled = br->stp_enabled; b.stp_enabled = br->stp_enabled;
b.ageing_time = br->ageing_time; b.ageing_time = br->ageing_time;
b.gc_interval = br->gc_interval; b.gc_interval = br->gc_interval;
b.hello_timer_value = br_timer_get_residue(&br->hello_timer); b.hello_timer_value = timer_residue(&br->hello_timer);
b.tcn_timer_value = br_timer_get_residue(&br->tcn_timer); b.tcn_timer_value = timer_residue(&br->tcn_timer);
b.topology_change_timer_value = br_timer_get_residue(&br->topology_change_timer); b.topology_change_timer_value = timer_residue(&br->topology_change_timer);
b.gc_timer_value = br_timer_get_residue(&br->gc_timer); b.gc_timer_value = timer_residue(&br->gc_timer);
read_unlock(&br->lock); read_unlock(&br->lock);
if (copy_to_user((void *)arg0, &b, sizeof(b))) if (copy_to_user((void *)arg0, &b, sizeof(b)))
...@@ -102,34 +117,34 @@ static int br_ioctl_device(struct net_bridge *br, ...@@ -102,34 +117,34 @@ static int br_ioctl_device(struct net_bridge *br,
case BRCTL_SET_BRIDGE_FORWARD_DELAY: case BRCTL_SET_BRIDGE_FORWARD_DELAY:
write_lock(&br->lock); write_lock(&br->lock);
br->bridge_forward_delay = arg0; br->bridge_forward_delay = user_to_ticks(arg0);
if (br_is_root_bridge(br)) if (br_is_root_bridge(br))
br->forward_delay = arg0; br->forward_delay = br->bridge_forward_delay;
write_unlock(&br->lock); write_unlock(&br->lock);
return 0; return 0;
case BRCTL_SET_BRIDGE_HELLO_TIME: case BRCTL_SET_BRIDGE_HELLO_TIME:
write_lock(&br->lock); write_lock(&br->lock);
br->bridge_hello_time = arg0; br->bridge_hello_time = user_to_ticks(arg0);
if (br_is_root_bridge(br)) if (br_is_root_bridge(br))
br->hello_time = arg0; br->hello_time = br->bridge_hello_time;
write_unlock(&br->lock); write_unlock(&br->lock);
return 0; return 0;
case BRCTL_SET_BRIDGE_MAX_AGE: case BRCTL_SET_BRIDGE_MAX_AGE:
write_lock(&br->lock); write_lock(&br->lock);
br->bridge_max_age = arg0; br->bridge_max_age = user_to_ticks(arg0);
if (br_is_root_bridge(br)) if (br_is_root_bridge(br))
br->max_age = arg0; br->max_age = br->bridge_max_age;
write_unlock(&br->lock); write_unlock(&br->lock);
return 0; return 0;
case BRCTL_SET_AGEING_TIME: case BRCTL_SET_AGEING_TIME:
br->ageing_time = arg0; br->ageing_time = user_to_ticks(arg0);
return 0; return 0;
case BRCTL_SET_GC_INTERVAL: case BRCTL_SET_GC_INTERVAL:
br->gc_interval = arg0; br->gc_interval = user_to_ticks(arg0);
return 0; return 0;
case BRCTL_GET_PORT_INFO: case BRCTL_GET_PORT_INFO:
...@@ -153,9 +168,9 @@ static int br_ioctl_device(struct net_bridge *br, ...@@ -153,9 +168,9 @@ static int br_ioctl_device(struct net_bridge *br,
p.state = pt->state; p.state = pt->state;
p.top_change_ack = pt->topology_change_ack; p.top_change_ack = pt->topology_change_ack;
p.config_pending = pt->config_pending; p.config_pending = pt->config_pending;
p.message_age_timer_value = br_timer_get_residue(&pt->message_age_timer); p.message_age_timer_value = timer_residue(&pt->message_age_timer);
p.forward_delay_timer_value = br_timer_get_residue(&pt->forward_delay_timer); p.forward_delay_timer_value = timer_residue(&pt->forward_delay_timer);
p.hold_timer_value = br_timer_get_residue(&pt->hold_timer); p.hold_timer_value = timer_residue(&pt->hold_timer);
read_unlock(&br->lock); read_unlock(&br->lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment