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