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

[BRIDGE]: Bridge confuses kernel user HZ.

parent 6eb563a4
......@@ -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);
......
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