From 520372a5f8d229afd7daaf2f5fa27707d6461f4f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger <shemminger@osdl.org> Date: Wed, 23 Apr 2003 10:32:52 -0700 Subject: [PATCH] [BRIDGE]: Bridge confuses kernel user HZ. --- net/bridge/br_ioctl.c | 45 ++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 7eda6d33c284..7e4e833ffc99 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -19,6 +19,21 @@ #include <asm/uaccess.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, unsigned int cmd, unsigned long arg0, @@ -70,10 +85,10 @@ static int br_ioctl_device(struct net_bridge *br, b.stp_enabled = br->stp_enabled; b.ageing_time = br->ageing_time; b.gc_interval = br->gc_interval; - b.hello_timer_value = br_timer_get_residue(&br->hello_timer); - b.tcn_timer_value = br_timer_get_residue(&br->tcn_timer); - b.topology_change_timer_value = br_timer_get_residue(&br->topology_change_timer); - b.gc_timer_value = br_timer_get_residue(&br->gc_timer); + b.hello_timer_value = timer_residue(&br->hello_timer); + b.tcn_timer_value = timer_residue(&br->tcn_timer); + b.topology_change_timer_value = timer_residue(&br->topology_change_timer); + b.gc_timer_value = timer_residue(&br->gc_timer); read_unlock(&br->lock); if (copy_to_user((void *)arg0, &b, sizeof(b))) @@ -102,34 +117,34 @@ static int br_ioctl_device(struct net_bridge *br, case BRCTL_SET_BRIDGE_FORWARD_DELAY: write_lock(&br->lock); - br->bridge_forward_delay = arg0; + br->bridge_forward_delay = user_to_ticks(arg0); if (br_is_root_bridge(br)) - br->forward_delay = arg0; + br->forward_delay = br->bridge_forward_delay; write_unlock(&br->lock); return 0; case BRCTL_SET_BRIDGE_HELLO_TIME: write_lock(&br->lock); - br->bridge_hello_time = arg0; + br->bridge_hello_time = user_to_ticks(arg0); if (br_is_root_bridge(br)) - br->hello_time = arg0; + br->hello_time = br->bridge_hello_time; write_unlock(&br->lock); return 0; case BRCTL_SET_BRIDGE_MAX_AGE: write_lock(&br->lock); - br->bridge_max_age = arg0; + br->bridge_max_age = user_to_ticks(arg0); if (br_is_root_bridge(br)) - br->max_age = arg0; + br->max_age = br->bridge_max_age; write_unlock(&br->lock); return 0; case BRCTL_SET_AGEING_TIME: - br->ageing_time = arg0; + br->ageing_time = user_to_ticks(arg0); return 0; case BRCTL_SET_GC_INTERVAL: - br->gc_interval = arg0; + br->gc_interval = user_to_ticks(arg0); return 0; case BRCTL_GET_PORT_INFO: @@ -153,9 +168,9 @@ static int br_ioctl_device(struct net_bridge *br, p.state = pt->state; p.top_change_ack = pt->topology_change_ack; p.config_pending = pt->config_pending; - p.message_age_timer_value = br_timer_get_residue(&pt->message_age_timer); - p.forward_delay_timer_value = br_timer_get_residue(&pt->forward_delay_timer); - p.hold_timer_value = br_timer_get_residue(&pt->hold_timer); + p.message_age_timer_value = timer_residue(&pt->message_age_timer); + p.forward_delay_timer_value = timer_residue(&pt->forward_delay_timer); + p.hold_timer_value = timer_residue(&pt->hold_timer); read_unlock(&br->lock); -- 2.30.9