Skip to content

Commit e3f336f

Browse files
committed
Merge: ipvs: speed up reads from ip_vs_conn proc file
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6185 JIRA: https://issues.redhat.com/browse/RHEL-74064 Upstream Status: net-next.git Signed-off-by: Florian Westphal <fwestpha@redhat.com> Approved-by: Guillaume Nault <gnault@redhat.com> Approved-by: Eric Garver <egarver@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Patrick Talbert <ptalbert@redhat.com>
2 parents cafeaa6 + 2dabc0c commit e3f336f

File tree

1 file changed

+28
-22
lines changed

1 file changed

+28
-22
lines changed

net/netfilter/ipvs/ip_vs_conn.c

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,28 +1046,35 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p, int dest_af,
10461046
#ifdef CONFIG_PROC_FS
10471047
struct ip_vs_iter_state {
10481048
struct seq_net_private p;
1049-
struct hlist_head *l;
1049+
unsigned int bucket;
1050+
unsigned int skip_elems;
10501051
};
10511052

1052-
static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos)
1053+
static void *ip_vs_conn_array(struct ip_vs_iter_state *iter)
10531054
{
10541055
int idx;
10551056
struct ip_vs_conn *cp;
1056-
struct ip_vs_iter_state *iter = seq->private;
10571057

1058-
for (idx = 0; idx < ip_vs_conn_tab_size; idx++) {
1058+
for (idx = iter->bucket; idx < ip_vs_conn_tab_size; idx++) {
1059+
unsigned int skip = 0;
1060+
10591061
hlist_for_each_entry_rcu(cp, &ip_vs_conn_tab[idx], c_list) {
10601062
/* __ip_vs_conn_get() is not needed by
10611063
* ip_vs_conn_seq_show and ip_vs_conn_sync_seq_show
10621064
*/
1063-
if (pos-- == 0) {
1064-
iter->l = &ip_vs_conn_tab[idx];
1065+
if (skip >= iter->skip_elems) {
1066+
iter->bucket = idx;
10651067
return cp;
10661068
}
1069+
1070+
++skip;
10671071
}
1072+
1073+
iter->skip_elems = 0;
10681074
cond_resched_rcu();
10691075
}
10701076

1077+
iter->bucket = idx;
10711078
return NULL;
10721079
}
10731080

@@ -1076,38 +1083,37 @@ static void *ip_vs_conn_seq_start(struct seq_file *seq, loff_t *pos)
10761083
{
10771084
struct ip_vs_iter_state *iter = seq->private;
10781085

1079-
iter->l = NULL;
10801086
rcu_read_lock();
1081-
return *pos ? ip_vs_conn_array(seq, *pos - 1) :SEQ_START_TOKEN;
1087+
if (*pos == 0) {
1088+
iter->skip_elems = 0;
1089+
iter->bucket = 0;
1090+
return SEQ_START_TOKEN;
1091+
}
1092+
1093+
return ip_vs_conn_array(iter);
10821094
}
10831095

10841096
static void *ip_vs_conn_seq_next(struct seq_file *seq, void *v, loff_t *pos)
10851097
{
10861098
struct ip_vs_conn *cp = v;
10871099
struct ip_vs_iter_state *iter = seq->private;
10881100
struct hlist_node *e;
1089-
struct hlist_head *l = iter->l;
1090-
int idx;
10911101

10921102
++*pos;
10931103
if (v == SEQ_START_TOKEN)
1094-
return ip_vs_conn_array(seq, 0);
1104+
return ip_vs_conn_array(iter);
10951105

10961106
/* more on same hash chain? */
10971107
e = rcu_dereference(hlist_next_rcu(&cp->c_list));
1098-
if (e)
1108+
if (e) {
1109+
iter->skip_elems++;
10991110
return hlist_entry(e, struct ip_vs_conn, c_list);
1100-
1101-
idx = l - ip_vs_conn_tab;
1102-
while (++idx < ip_vs_conn_tab_size) {
1103-
hlist_for_each_entry_rcu(cp, &ip_vs_conn_tab[idx], c_list) {
1104-
iter->l = &ip_vs_conn_tab[idx];
1105-
return cp;
1106-
}
1107-
cond_resched_rcu();
11081111
}
1109-
iter->l = NULL;
1110-
return NULL;
1112+
1113+
iter->skip_elems = 0;
1114+
iter->bucket++;
1115+
1116+
return ip_vs_conn_array(iter);
11111117
}
11121118

11131119
static void ip_vs_conn_seq_stop(struct seq_file *seq, void *v)

0 commit comments

Comments
 (0)