sctp: move hlist_node and hashent out of sctp_ep_common

Struct sctp_ep_common is included in both asoc and ep, but hlist_node
and hashent are only needed by ep after asoc_hashtable was dropped by
Commit b5eff71283 ("sctp: drop the old assoc hashtable of sctp").

So it is better to move hlist_node and hashent from sctp_ep_common to
sctp_endpoint, and it saves some space for each asoc.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Xin Long 2021-12-21 16:40:30 -05:00 committed by David S. Miller
parent e087cba116
commit 3d3b2f57d4
5 changed files with 23 additions and 32 deletions

View File

@ -510,8 +510,8 @@ static inline int sctp_ep_hashfn(struct net *net, __u16 lport)
return (net_hash_mix(net) + lport) & (sctp_ep_hashsize - 1); return (net_hash_mix(net) + lport) & (sctp_ep_hashsize - 1);
} }
#define sctp_for_each_hentry(epb, head) \ #define sctp_for_each_hentry(ep, head) \
hlist_for_each_entry(epb, head, node) hlist_for_each_entry(ep, head, node)
/* Is a socket of this style? */ /* Is a socket of this style? */
#define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style)) #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))

View File

@ -1243,10 +1243,6 @@ enum sctp_endpoint_type {
*/ */
struct sctp_ep_common { struct sctp_ep_common {
/* Fields to help us manage our entries in the hash tables. */
struct hlist_node node;
int hashent;
/* Runtime type information. What kind of endpoint is this? */ /* Runtime type information. What kind of endpoint is this? */
enum sctp_endpoint_type type; enum sctp_endpoint_type type;
@ -1298,6 +1294,10 @@ struct sctp_endpoint {
/* Common substructure for endpoint and association. */ /* Common substructure for endpoint and association. */
struct sctp_ep_common base; struct sctp_ep_common base;
/* Fields to help us manage our entries in the hash tables. */
struct hlist_node node;
int hashent;
/* Associations: A list of current associations and mappings /* Associations: A list of current associations and mappings
* to the data consumers for each association. This * to the data consumers for each association. This
* may be in the form of a hash table or other * may be in the form of a hash table or other

View File

@ -746,23 +746,21 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)
struct sock *sk = ep->base.sk; struct sock *sk = ep->base.sk;
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
struct sctp_hashbucket *head; struct sctp_hashbucket *head;
struct sctp_ep_common *epb;
epb = &ep->base; ep->hashent = sctp_ep_hashfn(net, ep->base.bind_addr.port);
epb->hashent = sctp_ep_hashfn(net, epb->bind_addr.port); head = &sctp_ep_hashtable[ep->hashent];
head = &sctp_ep_hashtable[epb->hashent];
if (sk->sk_reuseport) { if (sk->sk_reuseport) {
bool any = sctp_is_ep_boundall(sk); bool any = sctp_is_ep_boundall(sk);
struct sctp_ep_common *epb2; struct sctp_endpoint *ep2;
struct list_head *list; struct list_head *list;
int cnt = 0, err = 1; int cnt = 0, err = 1;
list_for_each(list, &ep->base.bind_addr.address_list) list_for_each(list, &ep->base.bind_addr.address_list)
cnt++; cnt++;
sctp_for_each_hentry(epb2, &head->chain) { sctp_for_each_hentry(ep2, &head->chain) {
struct sock *sk2 = epb2->sk; struct sock *sk2 = ep2->base.sk;
if (!net_eq(sock_net(sk2), net) || sk2 == sk || if (!net_eq(sock_net(sk2), net) || sk2 == sk ||
!uid_eq(sock_i_uid(sk2), sock_i_uid(sk)) || !uid_eq(sock_i_uid(sk2), sock_i_uid(sk)) ||
@ -789,7 +787,7 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)
} }
write_lock(&head->lock); write_lock(&head->lock);
hlist_add_head(&epb->node, &head->chain); hlist_add_head(&ep->node, &head->chain);
write_unlock(&head->lock); write_unlock(&head->lock);
return 0; return 0;
} }
@ -811,19 +809,16 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
{ {
struct sock *sk = ep->base.sk; struct sock *sk = ep->base.sk;
struct sctp_hashbucket *head; struct sctp_hashbucket *head;
struct sctp_ep_common *epb;
epb = &ep->base; ep->hashent = sctp_ep_hashfn(sock_net(sk), ep->base.bind_addr.port);
epb->hashent = sctp_ep_hashfn(sock_net(sk), epb->bind_addr.port); head = &sctp_ep_hashtable[ep->hashent];
head = &sctp_ep_hashtable[epb->hashent];
if (rcu_access_pointer(sk->sk_reuseport_cb)) if (rcu_access_pointer(sk->sk_reuseport_cb))
reuseport_detach_sock(sk); reuseport_detach_sock(sk);
write_lock(&head->lock); write_lock(&head->lock);
hlist_del_init(&epb->node); hlist_del_init(&ep->node);
write_unlock(&head->lock); write_unlock(&head->lock);
} }
@ -856,7 +851,6 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(
const union sctp_addr *paddr) const union sctp_addr *paddr)
{ {
struct sctp_hashbucket *head; struct sctp_hashbucket *head;
struct sctp_ep_common *epb;
struct sctp_endpoint *ep; struct sctp_endpoint *ep;
struct sock *sk; struct sock *sk;
__be16 lport; __be16 lport;
@ -866,8 +860,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(
hash = sctp_ep_hashfn(net, ntohs(lport)); hash = sctp_ep_hashfn(net, ntohs(lport));
head = &sctp_ep_hashtable[hash]; head = &sctp_ep_hashtable[hash];
read_lock(&head->lock); read_lock(&head->lock);
sctp_for_each_hentry(epb, &head->chain) { sctp_for_each_hentry(ep, &head->chain) {
ep = sctp_ep(epb);
if (sctp_endpoint_is_match(ep, net, laddr)) if (sctp_endpoint_is_match(ep, net, laddr))
goto hit; goto hit;
} }

View File

@ -161,7 +161,6 @@ static void *sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static int sctp_eps_seq_show(struct seq_file *seq, void *v) static int sctp_eps_seq_show(struct seq_file *seq, void *v)
{ {
struct sctp_hashbucket *head; struct sctp_hashbucket *head;
struct sctp_ep_common *epb;
struct sctp_endpoint *ep; struct sctp_endpoint *ep;
struct sock *sk; struct sock *sk;
int hash = *(loff_t *)v; int hash = *(loff_t *)v;
@ -171,18 +170,17 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
head = &sctp_ep_hashtable[hash]; head = &sctp_ep_hashtable[hash];
read_lock_bh(&head->lock); read_lock_bh(&head->lock);
sctp_for_each_hentry(epb, &head->chain) { sctp_for_each_hentry(ep, &head->chain) {
ep = sctp_ep(epb); sk = ep->base.sk;
sk = epb->sk;
if (!net_eq(sock_net(sk), seq_file_net(seq))) if (!net_eq(sock_net(sk), seq_file_net(seq)))
continue; continue;
seq_printf(seq, "%8pK %8pK %-3d %-3d %-4d %-5d %5u %5lu ", ep, sk, seq_printf(seq, "%8pK %8pK %-3d %-3d %-4d %-5d %5u %5lu ", ep, sk,
sctp_sk(sk)->type, sk->sk_state, hash, sctp_sk(sk)->type, sk->sk_state, hash,
epb->bind_addr.port, ep->base.bind_addr.port,
from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
sock_i_ino(sk)); sock_i_ino(sk));
sctp_seq_dump_local_addrs(seq, epb); sctp_seq_dump_local_addrs(seq, &ep->base);
seq_printf(seq, "\n"); seq_printf(seq, "\n");
} }
read_unlock_bh(&head->lock); read_unlock_bh(&head->lock);

View File

@ -5294,14 +5294,14 @@ int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
void *p) { void *p) {
int err = 0; int err = 0;
int hash = 0; int hash = 0;
struct sctp_ep_common *epb; struct sctp_endpoint *ep;
struct sctp_hashbucket *head; struct sctp_hashbucket *head;
for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize; for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
hash++, head++) { hash++, head++) {
read_lock_bh(&head->lock); read_lock_bh(&head->lock);
sctp_for_each_hentry(epb, &head->chain) { sctp_for_each_hentry(ep, &head->chain) {
err = cb(sctp_ep(epb), p); err = cb(ep, p);
if (err) if (err)
break; break;
} }