Hi Cyril,

On Tue, Aug 21, 2018 at 12:51:13PM +0200, Cyril Bonté wrote:
> Hi Willy,
> 
> I'm afraid there's still some issues with HTTP/2 in the current dev branch :-(
> 
> This morning, I've upgraded a test server and discovered that some HTTPS 
> sites did not work anymore (content hangs and is not sent to the client), 
> I've also noticed some segfaults in haproxy.
> As this is a test server that I've used for several years with haproxy, the 
> configuration begins to be quite ugly, it won't be helpful to provide it in 
> its current state.
> 

I think I figured those out, well at least I don't have hangs anymore, and
I think I understood those segfaults.
The attached patchset should do the trick.

Willy, those should be mergeable.

Thanks !

Olivier
>From 159f4653cffdd26fb62a26d047ac3f87f7506e59 Mon Sep 17 00:00:00 2001
From: Olivier Houchard <ohouch...@haproxy.com>
Date: Tue, 21 Aug 2018 14:25:52 +0200
Subject: [PATCH 1/5] BUG/MEDIUM: streams: Don't forget to remove the si from
 the wait list.

When freeing the stream, make sure we remove the stream interfaces from the
wait lists, in case it was in there.
---
 src/stream.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/stream.c b/src/stream.c
index bc0f1ac7..0f2ccf01 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -409,7 +409,9 @@ static void stream_free(struct stream *s)
                session_free(sess);
 
        tasklet_free(s->si[0].wait_list.task);
+       LIST_DEL(&s->si[0].wait_list.list);
        tasklet_free(s->si[1].wait_list.task);
+       LIST_DEL(&s->si[1].wait_list.list);
        pool_free(pool_head_stream, s);
 
        /* We may want to free the maximum amount of pools if the proxy is 
stopping */
-- 
2.14.3

>From 3c93f5ad9f6dd14114c01217a11d56455c1fe62d Mon Sep 17 00:00:00 2001
From: Olivier Houchard <ohouch...@haproxy.com>
Date: Fri, 17 Aug 2018 18:57:51 +0200
Subject: [PATCH 2/5] BUG/MEDIUM: tasklets: Add the thread as active when
 waking a tasklet.

Set the flag for the current thread in active_threads_mask when waking a
tasklet, or we will never run it if no tasks are available.
---
 include/proto/task.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/proto/task.h b/include/proto/task.h
index 13398c53..eef4ded4 100644
--- a/include/proto/task.h
+++ b/include/proto/task.h
@@ -226,6 +226,7 @@ static inline void tasklet_wakeup(struct tasklet *tl)
                return;
        LIST_ADDQ(&task_list[tid], &tl->list);
        task_list_size[tid]++;
+       HA_ATOMIC_OR(&active_tasks_mask, tid_bit);
        HA_ATOMIC_ADD(&tasks_run_queue, 1);
 
 }
-- 
2.14.3

>From 722665b5f60b65ad0eb035b6dd2162062dcbf42f Mon Sep 17 00:00:00 2001
From: Olivier Houchard <ohouch...@haproxy.com>
Date: Tue, 21 Aug 2018 15:59:43 +0200
Subject: [PATCH 3/5] BUG/MEDIUM: Check if the conn_stream exist in
 si_cs_io_cb.

It is possible that the conn_stream gets detached from the stream_interface,
and as it subscribed to the wait list, si_cs_io_cb() gets called anyway,
so make sure we have a conn_stream before attempting to send more data.
---
 src/stream_interface.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/stream_interface.c b/src/stream_interface.c
index 4b5b760c..52aa7c43 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -760,8 +760,12 @@ wake_others:
 struct task *si_cs_io_cb(struct task *t, void *ctx, unsigned short state)
 {
        struct stream_interface *si = ctx;
+       struct conn_stream *cs = objt_cs(si->end);
+
+       if (!cs)
+               return NULL;
        if (!(si->wait_list.wait_reason & SUB_CAN_SEND))
-               si_cs_send(__objt_cs(si->end));
+               si_cs_send(cs);
        return (NULL);
 }
 
-- 
2.14.3

>From bee74b66b702126dd7bd808d0f4037ba885441a2 Mon Sep 17 00:00:00 2001
From: Olivier Houchard <ohouch...@haproxy.com>
Date: Tue, 21 Aug 2018 16:36:10 +0200
Subject: [PATCH 4/5] BUG/MEDIUM: H2: Activate polling after successful
 h2_snd_buf().

Make sure h2_send() is called after h2_snd_buf() by activating polling.
---
 src/mux_h2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/mux_h2.c b/src/mux_h2.c
index 4a3150a2..7824cfe4 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -3531,6 +3531,8 @@ static size_t h2_snd_buf(struct conn_stream *cs, struct 
buffer *buf, size_t coun
        }
 
        b_del(buf, total);
+       if (total > 0)
+               conn_xprt_want_send(h2s->h2c->conn);
        return total;
 }
 
-- 
2.14.3

>From 64220c175bdc43fc82efc73c633be3b0212ab3e2 Mon Sep 17 00:00:00 2001
From: Olivier Houchard <ohouch...@haproxy.com>
Date: Tue, 21 Aug 2018 16:37:06 +0200
Subject: [PATCH 5/5] BUG/MEDIUM: stream_interface: Call the wake callback
 after sending.

If we subscribed to send, and the callback is called, call the wake callback
after, so that process_stream() may be woken up if needed.
---
 src/stream_interface.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/stream_interface.c b/src/stream_interface.c
index 52aa7c43..51f2300d 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -764,8 +764,10 @@ struct task *si_cs_io_cb(struct task *t, void *ctx, 
unsigned short state)
 
        if (!cs)
                return NULL;
-       if (!(si->wait_list.wait_reason & SUB_CAN_SEND))
+       if (!(si->wait_list.wait_reason & SUB_CAN_SEND)) {
                si_cs_send(cs);
+               si_cs_wake_cb(cs);
+       }
        return (NULL);
 }
 
-- 
2.14.3

Reply via email to