Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
1b4e3e1d
Commit
1b4e3e1d
authored
Jul 12, 2003
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPV4]: Kill slow timers from IPVS, they are superfluous and inefficient these days.
parent
08dbab2c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
6 additions
and
306 deletions
+6
-306
include/net/ip_vs.h
include/net/ip_vs.h
+1
-33
net/ipv4/ipvs/Makefile
net/ipv4/ipvs/Makefile
+1
-1
net/ipv4/ipvs/ip_vs_conn.c
net/ipv4/ipvs/ip_vs_conn.c
+4
-5
net/ipv4/ipvs/ip_vs_core.c
net/ipv4/ipvs/ip_vs_core.c
+0
-3
net/ipv4/ipvs/ip_vs_timer.c
net/ipv4/ipvs/ip_vs_timer.c
+0
-264
No files found.
include/net/ip_vs.h
View file @
1b4e3e1d
...
...
@@ -407,17 +407,6 @@ union ip_vs_tphdr {
};
/*
* Slow timer for IPVS connections
*/
struct
sltimer_list
{
struct
list_head
list
;
unsigned
long
expires
;
unsigned
long
data
;
void
(
*
function
)(
unsigned
long
);
};
/*
* Delta sequence info structure
* Each ip_vs_conn has 2 (output AND input seq. changes).
...
...
@@ -535,7 +524,7 @@ struct ip_vs_conn {
/* counter and timer */
atomic_t
refcnt
;
/* reference count */
struct
sl
timer_list
timer
;
/* Expiration timer */
struct
timer_list
timer
;
/* Expiration timer */
volatile
unsigned
long
timeout
;
/* timeout */
/* Flags and state transition */
...
...
@@ -939,27 +928,6 @@ extern int ip_vs_new_estimator(struct ip_vs_stats *stats);
extern
void
ip_vs_kill_estimator
(
struct
ip_vs_stats
*
stats
);
extern
void
ip_vs_zero_estimator
(
struct
ip_vs_stats
*
stats
);
/*
* Slow timer functions for IPVS
* (from ip_vs_timer.c)
*/
extern
void
add_sltimer
(
struct
sltimer_list
*
timer
);
extern
int
del_sltimer
(
struct
sltimer_list
*
timer
);
extern
void
mod_sltimer
(
struct
sltimer_list
*
timer
,
unsigned
long
expires
);
extern
void
ip_vs_sltimer_init
(
void
);
extern
void
ip_vs_sltimer_cleanup
(
void
);
static
inline
void
init_sltimer
(
struct
sltimer_list
*
timer
)
{
timer
->
list
.
next
=
timer
->
list
.
prev
=
NULL
;
}
static
inline
int
sltimer_pending
(
const
struct
sltimer_list
*
timer
)
{
return
timer
->
list
.
next
!=
NULL
;
}
/*
* Various IPVS packet transmitters (from ip_vs_xmit.c)
*/
...
...
net/ipv4/ipvs/Makefile
View file @
1b4e3e1d
...
...
@@ -16,7 +16,7 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_ESP) += ip_vs_proto_esp.o
ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH)
+=
ip_vs_proto_ah.o
ip_vs-objs
:=
ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o
\
ip_vs_xmit.o ip_vs_
timer.o ip_vs_app.o ip_vs_sync.o
\
ip_vs_xmit.o ip_vs_
app.o ip_vs_sync.o
\
ip_vs_est.o ip_vs_proto.o ip_vs_proto_icmp.o
\
$
(
ip_vs_proto-objs-y
)
...
...
net/ipv4/ipvs/ip_vs_conn.c
View file @
1b4e3e1d
...
...
@@ -282,7 +282,7 @@ struct ip_vs_conn *ip_vs_conn_out_get
void
ip_vs_conn_put
(
struct
ip_vs_conn
*
cp
)
{
/* reset it expire in its timeout */
mod_
sl
timer
(
&
cp
->
timer
,
jiffies
+
cp
->
timeout
);
mod_timer
(
&
cp
->
timer
,
jiffies
+
cp
->
timeout
);
__ip_vs_conn_put
(
cp
);
}
...
...
@@ -508,8 +508,7 @@ static void ip_vs_conn_expire(unsigned long data)
*/
if
(
likely
(
atomic_read
(
&
cp
->
refcnt
)
==
1
))
{
/* make sure that there is no timer on it now */
if
(
sltimer_pending
(
&
cp
->
timer
))
del_sltimer
(
&
cp
->
timer
);
del_timer_sync
(
&
cp
->
timer
);
/* does anybody control me? */
if
(
cp
->
control
)
...
...
@@ -542,7 +541,7 @@ static void ip_vs_conn_expire(unsigned long data)
void
ip_vs_conn_expire_now
(
struct
ip_vs_conn
*
cp
)
{
cp
->
timeout
=
0
;
mod_
sl
timer
(
&
cp
->
timer
,
jiffies
);
mod_timer
(
&
cp
->
timer
,
jiffies
);
__ip_vs_conn_put
(
cp
);
}
...
...
@@ -566,7 +565,7 @@ ip_vs_conn_new(int proto, __u32 caddr, __u16 cport, __u32 vaddr, __u16 vport,
memset
(
cp
,
0
,
sizeof
(
*
cp
));
INIT_LIST_HEAD
(
&
cp
->
c_list
);
init_
sl
timer
(
&
cp
->
timer
);
init_timer
(
&
cp
->
timer
);
cp
->
timer
.
data
=
(
unsigned
long
)
cp
;
cp
->
timer
.
function
=
ip_vs_conn_expire
;
cp
->
protocol
=
proto
;
...
...
net/ipv4/ipvs/ip_vs_core.c
View file @
1b4e3e1d
...
...
@@ -1092,7 +1092,6 @@ static int __init ip_vs_init(void)
goto
cleanup_nothing
;
}
ip_vs_sltimer_init
();
ip_vs_protocol_init
();
ret
=
ip_vs_app_init
();
...
...
@@ -1144,7 +1143,6 @@ static int __init ip_vs_init(void)
ip_vs_app_cleanup
();
cleanup_protocol:
ip_vs_protocol_cleanup
();
ip_vs_sltimer_cleanup
();
ip_vs_control_cleanup
();
cleanup_nothing:
return
ret
;
...
...
@@ -1159,7 +1157,6 @@ static void __exit ip_vs_cleanup(void)
ip_vs_conn_cleanup
();
ip_vs_app_cleanup
();
ip_vs_protocol_cleanup
();
ip_vs_sltimer_cleanup
();
ip_vs_control_cleanup
();
IP_VS_INFO
(
"ipvs unloaded.
\n
"
);
}
...
...
net/ipv4/ipvs/ip_vs_timer.c
deleted
100644 → 0
View file @
08dbab2c
/*
* IPVS An implementation of the IP virtual server support for the
* LINUX operating system. IPVS is now implemented as a module
* over the Netfilter framework. IPVS can be used to build a
* high-performance and highly available server based on a
* cluster of servers.
*
* Version: $Id: ip_vs_timer.c,v 1.11 2003/06/08 09:31:19 wensong Exp $
*
* Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
* Julian Anastasov <ja@ssi.bg>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Changes:
*
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <net/ip_vs.h>
/*
* The following block implements slow timers for IPVS, most code is stolen
* from linux/kernel/timer.c.
* Slow timer is used to avoid the overhead of cascading timers, when lots
* of connection entries (>50,000) are cluttered in the system.
*/
#define SHIFT_BITS 6
#define TVN_BITS 8
#define TVR_BITS 10
#define TVN_SIZE (1 << TVN_BITS)
#define TVR_SIZE (1 << TVR_BITS)
#define TVN_MASK (TVN_SIZE - 1)
#define TVR_MASK (TVR_SIZE - 1)
struct
sltimer_vec
{
int
index
;
struct
list_head
vec
[
TVN_SIZE
];
};
struct
sltimer_vec_root
{
int
index
;
struct
list_head
vec
[
TVR_SIZE
];
};
static
struct
sltimer_vec
sltv3
=
{
0
};
static
struct
sltimer_vec
sltv2
=
{
0
};
static
struct
sltimer_vec_root
sltv1
=
{
0
};
static
struct
sltimer_vec
*
const
sltvecs
[]
=
{
(
struct
sltimer_vec
*
)
&
sltv1
,
&
sltv2
,
&
sltv3
};
#define NOOF_SLTVECS (sizeof(sltvecs) / sizeof(sltvecs[0]))
static
void
init_sltimervecs
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
TVN_SIZE
;
i
++
)
{
INIT_LIST_HEAD
(
sltv3
.
vec
+
i
);
INIT_LIST_HEAD
(
sltv2
.
vec
+
i
);
}
for
(
i
=
0
;
i
<
TVR_SIZE
;
i
++
)
INIT_LIST_HEAD
(
sltv1
.
vec
+
i
);
}
static
unsigned
long
sltimer_jiffies
=
0
;
static
inline
void
internal_add_sltimer
(
struct
sltimer_list
*
timer
)
{
/*
* must hold the sltimer lock when calling this
*/
unsigned
long
expires
=
timer
->
expires
;
unsigned
long
idx
=
expires
-
sltimer_jiffies
;
struct
list_head
*
vec
;
if
(
idx
<
1
<<
(
SHIFT_BITS
+
TVR_BITS
))
{
int
i
=
(
expires
>>
SHIFT_BITS
)
&
TVR_MASK
;
vec
=
sltv1
.
vec
+
i
;
}
else
if
(
idx
<
1
<<
(
SHIFT_BITS
+
TVR_BITS
+
TVN_BITS
))
{
int
i
=
(
expires
>>
(
SHIFT_BITS
+
TVR_BITS
))
&
TVN_MASK
;
vec
=
sltv2
.
vec
+
i
;
}
else
if
((
signed
long
)
idx
<
0
)
{
/*
* can happen if you add a timer with expires == jiffies,
* or you set a timer to go off in the past
*/
vec
=
sltv1
.
vec
+
sltv1
.
index
;
}
else
if
(
idx
<=
0xffffffffUL
)
{
int
i
=
(
expires
>>
(
SHIFT_BITS
+
TVR_BITS
+
TVN_BITS
))
&
TVN_MASK
;
vec
=
sltv3
.
vec
+
i
;
}
else
{
/* Can only get here on architectures with 64-bit jiffies */
INIT_LIST_HEAD
(
&
timer
->
list
);
}
/*
* Timers are FIFO!
*/
list_add
(
&
timer
->
list
,
vec
->
prev
);
}
static
spinlock_t
__ip_vs_sltimerlist_lock
=
SPIN_LOCK_UNLOCKED
;
void
add_sltimer
(
struct
sltimer_list
*
timer
)
{
spin_lock
(
&
__ip_vs_sltimerlist_lock
);
if
(
timer
->
list
.
next
)
goto
bug
;
internal_add_sltimer
(
timer
);
out:
spin_unlock
(
&
__ip_vs_sltimerlist_lock
);
return
;
bug:
printk
(
"bug: kernel sltimer added twice at %p.
\n
"
,
__builtin_return_address
(
0
));
goto
out
;
}
static
inline
int
detach_sltimer
(
struct
sltimer_list
*
timer
)
{
if
(
!
sltimer_pending
(
timer
))
return
0
;
list_del
(
&
timer
->
list
);
return
1
;
}
void
mod_sltimer
(
struct
sltimer_list
*
timer
,
unsigned
long
expires
)
{
int
ret
;
spin_lock
(
&
__ip_vs_sltimerlist_lock
);
timer
->
expires
=
expires
;
ret
=
detach_sltimer
(
timer
);
internal_add_sltimer
(
timer
);
spin_unlock
(
&
__ip_vs_sltimerlist_lock
);
}
int
del_sltimer
(
struct
sltimer_list
*
timer
)
{
int
ret
;
spin_lock
(
&
__ip_vs_sltimerlist_lock
);
ret
=
detach_sltimer
(
timer
);
timer
->
list
.
next
=
timer
->
list
.
prev
=
0
;
spin_unlock
(
&
__ip_vs_sltimerlist_lock
);
return
ret
;
}
static
inline
void
cascade_sltimers
(
struct
sltimer_vec
*
tv
)
{
/*
* cascade all the timers from tv up one level
*/
struct
list_head
*
head
,
*
curr
,
*
next
;
head
=
tv
->
vec
+
tv
->
index
;
curr
=
head
->
next
;
/*
* We are removing _all_ timers from the list, so we don't have to
* detach them individually, just clear the list afterwards.
*/
while
(
curr
!=
head
)
{
struct
sltimer_list
*
tmp
;
tmp
=
list_entry
(
curr
,
struct
sltimer_list
,
list
);
next
=
curr
->
next
;
list_del
(
curr
);
// not needed
internal_add_sltimer
(
tmp
);
curr
=
next
;
}
INIT_LIST_HEAD
(
head
);
tv
->
index
=
(
tv
->
index
+
1
)
&
TVN_MASK
;
}
static
inline
void
run_sltimer_list
(
void
)
{
spin_lock
(
&
__ip_vs_sltimerlist_lock
);
while
((
long
)(
jiffies
-
sltimer_jiffies
)
>=
0
)
{
struct
list_head
*
head
,
*
curr
;
if
(
!
sltv1
.
index
)
{
int
n
=
1
;
do
{
cascade_sltimers
(
sltvecs
[
n
]);
}
while
(
sltvecs
[
n
]
->
index
==
1
&&
++
n
<
NOOF_SLTVECS
);
}
repeat:
head
=
sltv1
.
vec
+
sltv1
.
index
;
curr
=
head
->
next
;
if
(
curr
!=
head
)
{
struct
sltimer_list
*
timer
;
void
(
*
fn
)(
unsigned
long
);
unsigned
long
data
;
timer
=
list_entry
(
curr
,
struct
sltimer_list
,
list
);
fn
=
timer
->
function
;
data
=
timer
->
data
;
detach_sltimer
(
timer
);
timer
->
list
.
next
=
timer
->
list
.
prev
=
NULL
;
spin_unlock
(
&
__ip_vs_sltimerlist_lock
);
fn
(
data
);
spin_lock
(
&
__ip_vs_sltimerlist_lock
);
goto
repeat
;
}
sltimer_jiffies
+=
1
<<
SHIFT_BITS
;
sltv1
.
index
=
(
sltv1
.
index
+
1
)
&
TVR_MASK
;
}
spin_unlock
(
&
__ip_vs_sltimerlist_lock
);
}
static
struct
timer_list
slow_timer
;
/*
* Slow timer handler is activated every second
*/
#define SLTIMER_PERIOD 1*HZ
static
void
sltimer_handler
(
unsigned
long
data
)
{
run_sltimer_list
();
update_defense_level
();
if
(
atomic_read
(
&
ip_vs_dropentry
))
ip_vs_random_dropentry
();
mod_timer
(
&
slow_timer
,
(
jiffies
+
SLTIMER_PERIOD
));
}
void
ip_vs_sltimer_init
(
void
)
{
/* initialize the slow timer vectors */
init_sltimervecs
();
/* initialize the slow timer jiffies and the vector indexes */
sltimer_jiffies
=
jiffies
;
sltv1
.
index
=
(
sltimer_jiffies
>>
SHIFT_BITS
)
&
TVR_MASK
;
sltv2
.
index
=
(
sltimer_jiffies
>>
(
SHIFT_BITS
+
TVR_BITS
))
&
TVN_MASK
;
sltv3
.
index
=
(
sltimer_jiffies
>>
(
SHIFT_BITS
+
TVR_BITS
+
TVN_BITS
))
&
TVN_MASK
;
/* Hook the slow_timer handler in the system timer */
init_timer
(
&
slow_timer
);
slow_timer
.
function
=
sltimer_handler
;
slow_timer
.
expires
=
jiffies
+
SLTIMER_PERIOD
;
add_timer
(
&
slow_timer
);
}
void
ip_vs_sltimer_cleanup
(
void
)
{
del_timer_sync
(
&
slow_timer
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment