Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sctp: Avoid enqueuing addr events redundantly

Avoid modifying or enqueuing new events if it's possible to tell that no
one will consume them.

Since enqueueing requires searching the current queue for opposite
events for the same address, adding addresses en-masse turns this
inetaddr_event into a bottle-neck, as it will get slower and slower
with each address added.

Signed-off-by: Gilad Naaman <gnaaman@drivenets.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20241104083545.114-1-gnaaman@drivenets.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Gilad Naaman and committed by
Paolo Abeni
702c290a 2a6f99ee

+16 -2
+1 -1
net/sctp/ipv6.c
··· 103 103 ipv6_addr_equal(&addr->a.v6.sin6_addr, 104 104 &ifa->addr) && 105 105 addr->a.v6.sin6_scope_id == ifa->idev->dev->ifindex) { 106 - sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL); 107 106 found = 1; 108 107 addr->valid = 0; 109 108 list_del_rcu(&addr->list); 109 + sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL); 110 110 break; 111 111 } 112 112 }
+15 -1
net/sctp/protocol.c
··· 738 738 */ 739 739 740 740 spin_lock_bh(&net->sctp.addr_wq_lock); 741 + 742 + /* Avoid searching the queue or modifying it if there are no consumers, 743 + * as it can lead to performance degradation if addresses are modified 744 + * en-masse. 745 + * 746 + * If the queue already contains some events, update it anyway to avoid 747 + * ugly races between new sessions and new address events. 748 + */ 749 + if (list_empty(&net->sctp.auto_asconf_splist) && 750 + list_empty(&net->sctp.addr_waitq)) { 751 + spin_unlock_bh(&net->sctp.addr_wq_lock); 752 + return; 753 + } 754 + 741 755 /* Offsets existing events in addr_wq */ 742 756 addrw = sctp_addr_wq_lookup(net, addr); 743 757 if (addrw) { ··· 822 808 if (addr->a.sa.sa_family == AF_INET && 823 809 addr->a.v4.sin_addr.s_addr == 824 810 ifa->ifa_local) { 825 - sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL); 826 811 found = 1; 827 812 addr->valid = 0; 828 813 list_del_rcu(&addr->list); 814 + sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL); 829 815 break; 830 816 } 831 817 }