forked from iqiyi/dpvs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathip_vs_rr.c
88 lines (76 loc) · 2.21 KB
/
ip_vs_rr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
* DPVS is a software load balancer (Virtual Server) based on DPDK.
*
* Copyright (C) 2017 iQIYI (www.iqiyi.com).
* All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include "ipvs/rr.h"
static int dp_vs_rr_init_svc(struct dp_vs_service *svc)
{
svc->sched_data = &svc->dests;
return EDPVS_OK;
}
static int dp_vs_rr_update_svc(struct dp_vs_service *svc)
{
svc->sched_data = &svc->dests;
return EDPVS_OK;
}
/*
* Round-Robin Scheduling
*/
static struct dp_vs_dest *dp_vs_rr_schedule(struct dp_vs_service *svc,
const struct rte_mbuf *mbuf)
{
struct list_head *p, *q;
struct dp_vs_dest *dest;
rte_rwlock_write_lock(&svc->sched_lock);
p = (struct list_head *)svc->sched_data;
p = p->next;
q = p;
do {
/* skip list head */
if (q == &svc->dests) {
q = q->next;
continue;
}
dest = list_entry(q, struct dp_vs_dest, n_list);
if (!(dest->flags & DPVS_DEST_F_OVERLOAD) &&
rte_atomic16_read(&dest->weight) > 0)
/* HIT */
goto out;
q = q->next;
} while (q != p);
rte_rwlock_write_unlock(&svc->sched_lock);
return NULL;
out:
svc->sched_data = q;
rte_rwlock_write_unlock(&svc->sched_lock);
return dest;
}
static struct dp_vs_scheduler dp_vs_rr_scheduler = {
.name = "rr", /* name */
// .refcnt = ATOMIC_INIT(0),
.n_list = LIST_HEAD_INIT(dp_vs_rr_scheduler.n_list),
.init_service = dp_vs_rr_init_svc,
.update_service = dp_vs_rr_update_svc,
.schedule = dp_vs_rr_schedule,
};
int dp_vs_rr_init(void)
{
return register_dp_vs_scheduler(&dp_vs_rr_scheduler);
}
int dp_vs_rr_term(void)
{
return unregister_dp_vs_scheduler(&dp_vs_rr_scheduler);
}