[SSI] openssi/kernel/cluster/ssi/net ipvs_svr.c,1.27,1.28
Roger Tsang <[email protected]> Wed, 15 Dec 2010 08:01:53 +0000
| Newsgroups | gmane.linux.cluster.ssic.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/net
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv24416/kernel/cluster/ssi/net
Modified Files:
Tag: OPENSSI-FC
ipvs_svr.c
Log Message:
cluster/ssi/net/ipvs_svr.c
- __get_director: new macro to increment value of ipvs_refcnt field in ipvs_dirinfo structure.
- put_director: use BUG_ON() macro instead of SSI_ASSERT(). when the condition is not met memory corruption may occur.
- inaddr_any_op: release ipvs_directors_sem before calling ipvs_add/del_entry() which can go remote. reduce contention with del_cvip() path.
cluster/ssi/net/ipvs_svr.c (#ifdef IPVS_REGISTER_PORTS_FIX)
- register_port: new function based on for-loop section in register_ports(). release ipvs_directors_sem before calling ipvs_add/del_entry() which can go remote. reduce contention with _del_cvip() path.
- register_ports: invoke register_port().
Index: ipvs_svr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/net/ipvs_svr.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- ipvs_svr.c 17 Dec 2009 06:43:51 -0000 1.27
+++ ipvs_svr.c 15 Dec 2010 08:01:51 -0000 1.28
@@ -103,6 +103,8 @@
return info;
}
+#define __get_director(info) atomic_inc(&info->ipvs_refcnt)
+
struct ipvs_dirinfo *
get_director(__u32 ip)
{
@@ -112,7 +114,7 @@
list_for_each_entry(info, &ipvs_directors, list) {
if (info->daddr != ip)
continue;
- atomic_inc(&info->ipvs_refcnt);
+ __get_director(info);
up_read(&ipvs_directors_sem);
return info;
}
@@ -142,7 +144,7 @@
{
if (!atomic_dec_and_test(&info->ipvs_refcnt))
return;
- SSI_ASSERT(list_empty(&info->list));
+ BUG_ON(!list_empty(&info->list));
__del_directors(info);
kfree(info);
}
@@ -580,20 +582,32 @@
char *lvs_sched,
int is_addserv)
{
- struct ipvs_dirinfo *info;
+ struct ipvs_dirinfo *info, *tmp = NULL;
+
+ info = list_prepare_entry(tmp, &ipvs_directors, list);
down_read(&ipvs_directors_sem);
- list_for_each_entry(info, &ipvs_directors, list) {
+ list_for_each_entry_continue(info, &ipvs_directors, list) {
if (!is_configured(info->daddr))
continue;
- if (is_addserv)
+ __get_director(info);
+ up_read(&ipvs_directors_sem);
+
+ /* SSI_XXX: ignoring return value */
+ if (is_addserv) {
(void) ipvs_add_entry(info, port, rip, weight,
protocol, lvs_sched);
- else
+ } else
(void) ipvs_del_entry(info, port, rip, protocol);
- /* SSI_XXX: ignoring return value */
+
+ if (tmp)
+ put_director(tmp);
+ tmp = info;
+ down_read(&ipvs_directors_sem);
}
up_read(&ipvs_directors_sem);
+ if (tmp)
+ put_director(tmp);
return 0;
}
@@ -1055,6 +1069,40 @@
return 0;
}
+#ifdef IPVS_REGISTER_PORTS_FIX
+void
+register_port(
+ u_short port,
+ u_int rip,
+ int weight,
+ u_short protocol,
+ char *lvs_sched)
+{
+ struct ipvs_dirinfo *info, *tmp = NULL;
+
+ info = list_prepare_entry(tmp, &ipvs_directors, list);
+
+ down_read(&ipvs_directors_sem);
+ list_for_each_entry_continue(info, &ipvs_directors, list) {
+ if (!is_configured(info->daddr) ||
+ !is_bound(port, protocol, info->daddr))
+ continue;
+ __get_director(info);
+ up_read(&ipvs_directors_sem);
+
+ (void) ipvs_add_entry(info, port, rip, weight,
+ protocol, lvs_sched);
+ if (tmp)
+ put_director(tmp);
+ tmp = info;
+ down_read(&ipvs_directors_sem);
+ }
+ up_read(&ipvs_directors_sem);
+ if (tmp)
+ put_director(tmp);
+}
+#endif /* IPVS_REGISTER_PORTS_FIX */
+
/**
* register_ports: Register the network services already listening to the director node
*/
@@ -1070,38 +1118,24 @@
icsinfo_t nodeinfo;
u_short port;
#ifdef IPVS_REGISTER_PORTS_FIX
- struct ipvs_dirinfo *info;
-
/* ICS interface address is the real server address*/
if (ics_geticsinfo(this_node, &nodeinfo))
return;
-
rip = in_aton((char*)&nodeinfo);
-#endif
for (port = start_port; port <= end_port; port++) {
-#ifdef IPVS_REGISTER_PORTS_FIX
if (getport_desc(port, protocol, NULL))
continue;
-
if (!weight) {
/* Unregister port for ha-lvs unconfigure_services() */
(void) inaddr_any_op(htons(port), rip, weight, protocol,
lvs_sched, 0);
- continue;
- }
-
- down_read(&ipvs_directors_sem);
- list_for_each_entry(info, &ipvs_directors, list) {
- if (!is_configured(info->daddr) ||
- !is_bound(port, protocol, info->daddr))
- continue;
-
- (void) ipvs_add_entry(info, htons(port), rip, weight,
+ } else
+ register_port(htons(port), rip, weight,
protocol, lvs_sched);
- }
- up_read(&ipvs_directors_sem);
-#else
+ }
+#else /* IPVS_REGISTER_PORTS_FIX */
+ for (port = start_port; port <= end_port; port++) {
if (!is_bound(port, protocol))
continue;
@@ -1117,8 +1151,8 @@
* registered with all the cvips
*/
(void) inaddr_any_op(htons(port), rip, weight, protocol, lvs_sched, 1);
-#endif
}
+#endif /* !IPVS_REGISTER_PORTS_FIX */
}
static int
@@ -1281,13 +1315,15 @@
#ifdef IPVS_SERVICE_RACE_FIX
port = inet->sport;
+ /* NB: no race. update_ipvs_portweight_list() does not remove entries */
if (getport_desc(ntohs(port), protocol, NULL))
goto con_sock;
ret = del_ipvs_entry(cvip, port, rip, protocol);
if (ret) {
- printk(KERN_ALERT "%s: delete IPVS real server %s:%d failed %d\n",
- __FUNCTION__, (char *)&nodeinfo, port, ret);
+ printk(KERN_NOTICE "%s: delete IPVS real server %s:%d "
+ "failed %d\n", __FUNCTION__, (char *)&nodeinfo,
+ port, ret);
}
#else
/* SSI_XXX: Not interested in the return value ?! */
------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d