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#define KMSG_COMPONENT "IPVS"
35#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
36
37#include <linux/module.h>
38#include <linux/kernel.h>
39
40#include <net/ip_vs.h>
41
42
43static inline unsigned int
44ip_vs_nq_dest_overhead(struct ip_vs_dest *dest)
45{
46
47
48
49
50 return atomic_read(&dest->activeconns) + 1;
51}
52
53
54
55
56
57static struct ip_vs_dest *
58ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
59{
60 struct ip_vs_dest *dest, *least = NULL;
61 unsigned int loh = 0, doh;
62
63 IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 list_for_each_entry(dest, &svc->destinations, n_list) {
79
80 if (dest->flags & IP_VS_DEST_F_OVERLOAD ||
81 !atomic_read(&dest->weight))
82 continue;
83
84 doh = ip_vs_nq_dest_overhead(dest);
85
86
87 if (atomic_read(&dest->activeconns) == 0) {
88 least = dest;
89 loh = doh;
90 goto out;
91 }
92
93 if (!least ||
94 (loh * atomic_read(&dest->weight) >
95 doh * atomic_read(&least->weight))) {
96 least = dest;
97 loh = doh;
98 }
99 }
100
101 if (!least) {
102 IP_VS_ERR_RL("NQ: no destination available\n");
103 return NULL;
104 }
105
106 out:
107 IP_VS_DBG_BUF(6, "NQ: server %s:%u "
108 "activeconns %d refcnt %d weight %d overhead %d\n",
109 IP_VS_DBG_ADDR(svc->af, &least->addr), ntohs(least->port),
110 atomic_read(&least->activeconns),
111 atomic_read(&least->refcnt),
112 atomic_read(&least->weight), loh);
113
114 return least;
115}
116
117
118static struct ip_vs_scheduler ip_vs_nq_scheduler =
119{
120 .name = "nq",
121 .refcnt = ATOMIC_INIT(0),
122 .module = THIS_MODULE,
123 .n_list = LIST_HEAD_INIT(ip_vs_nq_scheduler.n_list),
124 .schedule = ip_vs_nq_schedule,
125};
126
127
128static int __init ip_vs_nq_init(void)
129{
130 return register_ip_vs_scheduler(&ip_vs_nq_scheduler);
131}
132
133static void __exit ip_vs_nq_cleanup(void)
134{
135 unregister_ip_vs_scheduler(&ip_vs_nq_scheduler);
136}
137
138module_init(ip_vs_nq_init);
139module_exit(ip_vs_nq_cleanup);
140MODULE_LICENSE("GPL");
141