FreeBSD Bugzilla – Attachment 231307 Details for
Bug 260116
[sctp] POLLOUT/EVFILT_WRITE is always true for poll/kqueue
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Proposed patch
0001-Handle-POLLOUT-EVFILT_WRITE-when-send-buffer-is-full.patch (text/plain), 6.67 KB, created by
Björn Svensson
on 2022-01-25 11:09:13 UTC
(
hide
)
Description:
Proposed patch
Filename:
MIME Type:
Creator:
Björn Svensson
Created:
2022-01-25 11:09:13 UTC
Size:
6.67 KB
patch
obsolete
>From b3690ea4dad191b613b526d4cb4bc0d985929403 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= <bjorn.a.svensson@est.tech> >Date: Tue, 25 Jan 2022 10:35:30 +0000 >Subject: [PATCH] Handle POLLOUT/EVFILT_WRITE when send buffer is full > >Since the socket buffer counter sb_cc has been split into sb_ccc and >sb_acc, and both are used, there is a need to update both counters. >Currently sb_acc is used as sb_cc to enable select(), but sb_ccc is >required to be updated as well for the poll events and Kqueue filters. > >This adds a macro for unifying the sb_acc and sb_ccc counters when >there is a need to update the value. >The macro can be changed for upstream users in a similar way as for >the use of sb_cc, i.e. it can be disabled when there is a need to >keep the old way of only using sb_cc. >--- > sys/netinet/sctp_input.c | 1 + > sys/netinet/sctp_os_bsd.h | 7 ++++++- > sys/netinet/sctp_output.c | 1 + > sys/netinet/sctp_structs.h | 1 + > sys/netinet/sctp_usrreq.c | 1 + > sys/netinet/sctp_var.h | 4 ++++ > sys/netinet/sctputil.c | 2 ++ > sys/netinet/sctputil.h | 3 +++ > 8 files changed, 19 insertions(+), 1 deletion(-) > >diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c >index ce017b74b67..34f162db5e0 100644 >--- a/sys/netinet/sctp_input.c >+++ b/sys/netinet/sctp_input.c >@@ -995,6 +995,7 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED, > if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || > (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { > stcb->sctp_socket->so_snd.sb_cc = 0; >+ SCTP_UNIFY_SB_CC(&stcb->sctp_socket->so_snd); > } > sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED); > } >diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h >index 39c0a8cb5c2..159ba58a52c 100644 >--- a/sys/netinet/sctp_os_bsd.h >+++ b/sys/netinet/sctp_os_bsd.h >@@ -378,6 +378,10 @@ typedef struct callout sctp_os_timer_t; > * with SCTP sockets. > */ > #define sb_cc sb_acc >+/* Since both sb_acc and sb_ccc are used by the framework we need >+ * to make sure the values are unified, e.g. POLL/EVFILT uses sb_ccc. >+ */ >+#define SCTP_UNIFY_SB_CC(sb) (atomic_store_int(&(sb)->sb_ccc, (sb)->sb_acc)) > /* reserve sb space for a socket */ > #define SCTP_SORESERVE(so, send, recv) soreserve(so, send, recv) > /* wakeup a socket */ >@@ -386,7 +390,8 @@ typedef struct callout sctp_os_timer_t; > #define SCTP_SB_CLEAR(sb) \ > (sb).sb_cc = 0; \ > (sb).sb_mb = NULL; \ >- (sb).sb_mbcnt = 0; >+ (sb).sb_mbcnt = 0; \ >+ SCTP_UNIFY_SB_CC(&sb); > > #define SCTP_SB_LIMIT_RCV(so) (SOLISTENING(so) ? so->sol_sbrcv_hiwat : so->so_rcv.sb_hiwat) > #define SCTP_SB_LIMIT_SND(so) (SOLISTENING(so) ? so->sol_sbsnd_hiwat : so->so_snd.sb_hiwat) >diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c >index 277a6625aa1..66f81eeb016 100644 >--- a/sys/netinet/sctp_output.c >+++ b/sys/netinet/sctp_output.c >@@ -7258,6 +7258,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, > ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || > (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { > atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_cc, sp->length); >+ SCTP_UNIFY_SB_CC(&stcb->sctp_socket->so_snd); > } > if (sp->data) { > sctp_m_freem(sp->data); >diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h >index a22dac04797..2af2661dc4c 100644 >--- a/sys/netinet/sctp_structs.h >+++ b/sys/netinet/sctp_structs.h >@@ -1003,6 +1003,7 @@ struct sctp_association { > uint32_t total_output_queue_size; > > uint32_t sb_cc; /* shadow of sb_cc */ >+ uint32_t sb_ccc; /* shadow of sb_ccc */ > uint32_t sb_send_resv; /* amount reserved on a send */ > uint32_t my_rwnd_control_len; /* shadow of sb_mbcnt used for rwnd > * control */ >diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c >index 2dad0b41a30..3109830f76a 100644 >--- a/sys/netinet/sctp_usrreq.c >+++ b/sys/netinet/sctp_usrreq.c >@@ -838,6 +838,7 @@ sctp_flush(struct socket *so, int how) > * except maybe the count > */ > so->so_snd.sb_cc = 0; >+ SCTP_UNIFY_SB_CC(&so->so_snd); > so->so_snd.sb_mbcnt = 0; > so->so_snd.sb_mb = NULL; > } >diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h >index ed01de7d701..2ca5501fa2a 100644 >--- a/sys/netinet/sctp_var.h >+++ b/sys/netinet/sctp_var.h >@@ -199,9 +199,11 @@ extern struct pr_usrreqs sctp_usrreqs; > > #define sctp_sbfree(ctl, stcb, sb, m) { \ > SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \ >+ SCTP_UNIFY_SB_CC(sb); \ > SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_mbcnt, MSIZE); \ > if (((ctl)->do_not_ref_stcb == 0) && stcb) {\ > SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \ >+ SCTP_UNIFY_SB_CC(&(stcb)->asoc); \ > SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.my_rwnd_control_len, MSIZE); \ > } \ > if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \ >@@ -211,9 +213,11 @@ extern struct pr_usrreqs sctp_usrreqs; > > #define sctp_sballoc(stcb, sb, m) { \ > atomic_add_int(&(sb)->sb_cc,SCTP_BUF_LEN((m))); \ >+ SCTP_UNIFY_SB_CC(sb); \ > atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \ > if (stcb) { \ > atomic_add_int(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \ >+ SCTP_UNIFY_SB_CC(&(stcb)->asoc); \ > atomic_add_int(&(stcb)->asoc.my_rwnd_control_len, MSIZE); \ > } \ > if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \ >diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c >index 42e91e10a0d..a96b01d95e2 100644 >--- a/sys/netinet/sctputil.c >+++ b/sys/netinet/sctputil.c >@@ -5045,6 +5045,7 @@ sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc, > } else { > stcb->sctp_socket->so_snd.sb_cc = 0; > } >+ SCTP_UNIFY_SB_CC(&stcb->sctp_socket->so_snd); > } > } > >@@ -6127,6 +6128,7 @@ sctp_sorecvmsg(struct socket *so, > if ((control->do_not_ref_stcb == 0) && > stcb) { > atomic_subtract_int(&stcb->asoc.sb_cc, cp_len); >+ SCTP_UNIFY_SB_CC(&stcb->asoc); > } > copied_so_far += cp_len; > freed_so_far += (uint32_t)cp_len; >diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h >index 3319eb4f455..8e8b8749860 100644 >--- a/sys/netinet/sctputil.h >+++ b/sys/netinet/sctputil.h >@@ -264,6 +264,7 @@ do { \ > } else { \ > stcb->sctp_socket->so_snd.sb_cc = 0; \ > } \ >+ SCTP_UNIFY_SB_CC(&stcb->sctp_socket->so_snd); \ > } \ > } \ > } while (0) >@@ -285,6 +286,7 @@ do { \ > } else { \ > stcb->sctp_socket->so_snd.sb_cc = 0; \ > } \ >+ SCTP_UNIFY_SB_CC(&stcb->sctp_socket->so_snd); \ > } \ > } \ > } while (0) >@@ -296,6 +298,7 @@ do { \ > ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \ > (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \ > atomic_add_int(&stcb->sctp_socket->so_snd.sb_cc,sz); \ >+ SCTP_UNIFY_SB_CC(&stcb->sctp_socket->so_snd); \ > } \ > } while (0) > >-- >2.34.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 260116
:
229791
|
231307
|
231650