Re: Peers using heavily single cpu core

2022-05-22 Thread Willy Tarreau
Hi Maciej,

On Mon, May 23, 2022 at 08:50:53AM +0200, Maciej Zdeb wrote:
> Hi Christopher,
> I've verified that outgoing connections are now spread between multiple
> threads! Thank you very much!

That's really great, thank you for testing! I, too, thought it was
worth being merged even this late in the dev cycle. The way it was
done allows to postpone conversion of other applets, so the risk of
breaking something remains fairly limited. We'll see.

Cheers,
Willy



Re: Peers using heavily single cpu core

2022-05-22 Thread Maciej Zdeb
Hi Christopher,
I've verified that outgoing connections are now spread between multiple
threads! Thank you very much!

23 : st=0x000121(cl heopI W:sRa R:srA) tmask=0x8 umask=0x0
owner=0x56219da29280 iocb=0x56219cdc8730(sock_conn_iocb) back=0
cflg=0x0300 fam=ipv4 lport=1024 rport=52046 fe=hap1 mux=PASS
ctx=0x7f4c2002f410 xprt=RAW
24 : st=0x000121(cl heopI W:sRa R:srA) tmask=0x20 umask=0x0
owner=0x7f4c2802a7a0 iocb=0x56219cdc8730(sock_conn_iocb) back=0
cflg=0x0300 fam=ipv4 lport=1024 rport=55428 fe=hap1 mux=PASS
ctx=0x7f4c2c02f200 xprt=RAW
25 : st=0x000121(cl heopI W:sRa R:srA) tmask=0x1 umask=0x0
owner=0x7f4c2c0260b0 iocb=0x56219cdc8730(sock_conn_iocb) back=0
cflg=0x0300 fam=ipv4 lport=1024 rport=51190 fe=hap1 mux=PASS
ctx=0x56219da24180 xprt=RAW
26 : st=0x010121(cL heopI W:sRa R:srA) tmask=0x20 umask=0x0
owner=0x7f4c2c026ac0 iocb=0x56219cdc8730(sock_conn_iocb) back=1
cflg=0x1300 fam=ipv4 lport=34454 rport=1024 px=hap1 mux=PASS
ctx=0x7f4c2c026610 xprt=RAW
27 : st=0x000121(cl heopI W:sRa R:srA) tmask=0x4 umask=0x0
owner=0x7f4c40026cf0 iocb=0x56219cdc8730(sock_conn_iocb) back=0
cflg=0x0300 fam=ipv4 lport=1024 rport=50226 fe=hap1 mux=PASS
ctx=0x7f4c3002eb60 xprt=RAW

Kind regards,

wt., 17 maj 2022 o 16:25 Christopher Faulet 
napisał(a):

> Le 4/20/22 à 14:51, Maciej Zdeb a écrit :
> > Hi Willy,
> > I saw Christopher changes are now merged. I was wondering how to proceed
> with my
> > issue. Right now in stream_new() I'm able to get cs_endpoint and appctx
> (if
> > endpoint is applet), so I can get thread_mask of appctx to create a
> stream task
> > on the same thread. Is this approach correct?
> >
>
> Hi Maciej,
>
> I've finally finish my applet refactoring. Now it is possible to choose
> where to
> start an applet. I've also merged your patches. Peer applets must now be
> balanced across threads. So, you may give it a try to be sure it solves
> your
> issue and also validate everything works fine.
>
> --
> Christopher Faulet
>


Re: Peers using heavily single cpu core

2022-05-17 Thread Christopher Faulet

Le 4/20/22 à 14:51, Maciej Zdeb a écrit :

Hi Willy,
I saw Christopher changes are now merged. I was wondering how to proceed with my 
issue. Right now in stream_new() I'm able to get cs_endpoint and appctx (if 
endpoint is applet), so I can get thread_mask of appctx to create a stream task 
on the same thread. Is this approach correct?




Hi Maciej,

I've finally finish my applet refactoring. Now it is possible to choose where to 
start an applet. I've also merged your patches. Peer applets must now be 
balanced across threads. So, you may give it a try to be sure it solves your 
issue and also validate everything works fine.


--
Christopher Faulet



Re: Peers using heavily single cpu core

2022-04-20 Thread Maciej Zdeb
No worries, thanks for the update.

Kind regards,
Maciej

śr., 20 kwi 2022 o 21:59 Willy Tarreau  napisał(a):

> Hi Maciej,
>
> On Wed, Apr 20, 2022 at 02:51:32PM +0200, Maciej Zdeb wrote:
> > Hi Willy,
> > I saw Christopher changes are now merged. I was wondering how to proceed
> > with my issue. Right now in stream_new() I'm able to get cs_endpoint and
> > appctx (if endpoint is applet), so I can get thread_mask of appctx to
> > create a stream task on the same thread. Is this approach correct?
>
> It's still not possible at this stage. The related modifications still
> have to be done. We've discussed about this today and these still seem
> possible but it's difficult to estimate if it will be done easily or
> if we'll discover new showstoppers. I'd suggest that you wait a bit
> more, I'm afraid.
>
> Cheers,
> Willy
>


Re: Peers using heavily single cpu core

2022-04-20 Thread Willy Tarreau
Hi Maciej,

On Wed, Apr 20, 2022 at 02:51:32PM +0200, Maciej Zdeb wrote:
> Hi Willy,
> I saw Christopher changes are now merged. I was wondering how to proceed
> with my issue. Right now in stream_new() I'm able to get cs_endpoint and
> appctx (if endpoint is applet), so I can get thread_mask of appctx to
> create a stream task on the same thread. Is this approach correct?

It's still not possible at this stage. The related modifications still
have to be done. We've discussed about this today and these still seem
possible but it's difficult to estimate if it will be done easily or
if we'll discover new showstoppers. I'd suggest that you wait a bit
more, I'm afraid.

Cheers,
Willy



Re: Peers using heavily single cpu core

2022-04-20 Thread Maciej Zdeb
Hi Willy,
I saw Christopher changes are now merged. I was wondering how to proceed
with my issue. Right now in stream_new() I'm able to get cs_endpoint and
appctx (if endpoint is applet), so I can get thread_mask of appctx to
create a stream task on the same thread. Is this approach correct?

Kind regards

czw., 7 kwi 2022 o 22:32 Maciej Zdeb  napisał(a):

> Hi Willy,
> I adjusted the 3rd patch to use HA_ATOMIC_INC/HA_ATOMIC_DEC. Thanks!
>
> czw., 7 kwi 2022 o 14:02 Willy Tarreau  napisał(a):
>
>> There are some ongoing changes in that area that are about to be merged
>> (probably early
>> next week) and that will help for this task, so we'll have a closer look,
>> and it's very likely that we could proceed like this soon.
>>
>
> Great! I must admit that I imagined a stream_new_on() function but after
> looking at stream_new() I thought I'd better ask for help. ;-)
>
> Kind regards,
> Maciej
>
>


Re: Peers using heavily single cpu core

2022-04-07 Thread Maciej Zdeb
Hi Willy,
I adjusted the 3rd patch to use HA_ATOMIC_INC/HA_ATOMIC_DEC. Thanks!

czw., 7 kwi 2022 o 14:02 Willy Tarreau  napisał(a):

> There are some ongoing changes in that area that are about to be merged
> (probably early
> next week) and that will help for this task, so we'll have a closer look,
> and it's very likely that we could proceed like this soon.
>

Great! I must admit that I imagined a stream_new_on() function but after
looking at stream_new() I thought I'd better ask for help. ;-)

Kind regards,
Maciej


0002-MINOR-peers-Track-number-of-applets-run-by-thread.patch
Description: Binary data


0003-MINOR-peers-Balance-applets-across-threads.patch
Description: Binary data


0001-MINOR-applet-Add-function-to-create-applet-on-select.patch
Description: Binary data


Re: Peers using heavily single cpu core

2022-04-07 Thread Willy Tarreau
On Thu, Apr 07, 2022 at 11:50:33AM +0200, Willy Tarreau wrote:
> And in an ideal world, the applet's init code could be the one responsible
> for creating its stream. Historically it wasn't even possible because both
> contexts were strongly tied. But with the changes Christopher recently did
> to keep the applets away, maybe that's something we can think of. If so,
> that would also make the Lua client and http_client setup code so much
> cleaner, I'll discuss this with Christopher to see what's missing to
> reach that point, and will get back to you ASAP (or please yell at me
> if you don't hear about me for some time).

So after discussing about this, it seems to make sense. There are some
ongoing changes in that area that are about to be merged (probably early
next week) and that will help for this task, so we'll have a closer look,
and it's very likely that we could proceed like this soon.

Stay tuned!
Willy



Re: Peers using heavily single cpu core

2022-04-07 Thread Willy Tarreau
Hi Maciej,

On Wed, Apr 06, 2022 at 11:17:44AM +0200, Maciej Zdeb wrote:
> Hi Willy,
> 
> I've managed to implement the easy part (attached patches).

Thanks for this! I'm having a minor comment on the 3rd patch, see at
the end.

> However this is
> not enough to get it to work properly. I'm stuck in a debug of following
> stack trace (BUG_ON task_queue() function):
> 
> FATAL: bug condition "task->thread_mask != tid_bit" matched at
> include/haproxy/task.h:320
>   call trace(12):
>   | 0x55f921169be3 [c7 04 25 01 00 00 00 00]: main+0x112f53
>   | 0x55f92116c4ee [48 8b 43 08 48 8b 78 10]: si_applet_wake_cb+0x7e/0xf3
>   | 0x55f9211cc276 [48 8b 43 08 48 8b 40 10]: task_run_applet+0x196/0x5bd
>   | 0x55f92118e6ca [48 89 c5 eb 0f 90 4c 89]:
> run_tasks_from_lists+0x3aa/0x871
>   | 0x55f92118ef73 [29 44 24 14 8b 7c 24 14]:
> process_runnable_tasks+0x3d3/0x892
>   | 0x55f92115eb44 [83 3d f9 ef 1d 00 01 0f]: run_poll_loop+0x124/0x3d4
>   | 0x55f92115efc9 [48 8b 1d d0 94 12 00 4c]: main+0x108339
>   | 0x55f9210589ff [31 c0 e8 ba a6 16 00 31]: main+0x1d6f/0x296a
> 
> I'm not sure why it happens. I suspect that it happens because of
> session_new() in peer_session_create() that creates another task on the
> current thread. If a session task tries to wake up a peer applet task then
> it would explain the stack trace, however I've failed to fully understand
> the "flow" between applet and session (and how/when task_queue is called in
> this flow). I would appreciate any help or tips on how to proceed.

I hadn't thought about that, as usual the devil is in the details :-(

The problem here is that it's not allowed to requeue a task that belongs
to another thread, and that's exactly what is being done there, because
while the applet runs on its target thread, it's bound to a stream that
was programmed for another thread, and when requeuing its task it fails.

We could imagine having a stream_new_on() but that's not realistic
because stream_new() already touches some thread-specific stuff and
even calls the frontend's accept() function or initializes streams.

Thus if we sum up, it's not possible to create a stream for another thread,
but functionally speaking, that's not something we absolutely want to do,
we would also be fine with having someone else create such a stream. And
in an ideal world, the applet's init code could be the one responsible
for creating its stream. Historically it wasn't even possible because both
contexts were strongly tied. But with the changes Christopher recently did
to keep the applets away, maybe that's something we can think of. If so,
that would also make the Lua client and http_client setup code so much
cleaner, I'll discuss this with Christopher to see what's missing to
reach that point, and will get back to you ASAP (or please yell at me
if you don't hear about me for some time).

Regarding the comment on the 3rd patch:

> From c7f1be0dab823b81a1806d8eaca906d9c2483ac8 Mon Sep 17 00:00:00 2001
> From: Maciej Zdeb 
> Date: Mon, 4 Apr 2022 13:08:11 +0200
> Subject: [PATCH 3/3] MINOR: peers: Balance applets across threads
> 
(...)
> @@ -3236,7 +3240,7 @@ static struct appctx *peer_session_create(struct peers 
> *peers, struct peer *peer
>  
>   s->res.flags |= CF_READ_DONTWAIT;
>  
> - peers->applet_count[tid]++;
> + peers->applet_count[thr]++;

You'll need to switch to:

HA_ATOMIC_INC(&peers->applet_count[thr]);

instead. Indeed, since the counter belongs to another thread, any other
thread could be manipulating it at the same time.

thanks!
Willy



Re: Peers using heavily single cpu core

2022-04-06 Thread Maciej Zdeb
Hi Willy,

I've managed to implement the easy part (attached patches). However this is
not enough to get it to work properly. I'm stuck in a debug of following
stack trace (BUG_ON task_queue() function):

FATAL: bug condition "task->thread_mask != tid_bit" matched at
include/haproxy/task.h:320
  call trace(12):
  | 0x55f921169be3 [c7 04 25 01 00 00 00 00]: main+0x112f53
  | 0x55f92116c4ee [48 8b 43 08 48 8b 78 10]: si_applet_wake_cb+0x7e/0xf3
  | 0x55f9211cc276 [48 8b 43 08 48 8b 40 10]: task_run_applet+0x196/0x5bd
  | 0x55f92118e6ca [48 89 c5 eb 0f 90 4c 89]:
run_tasks_from_lists+0x3aa/0x871
  | 0x55f92118ef73 [29 44 24 14 8b 7c 24 14]:
process_runnable_tasks+0x3d3/0x892
  | 0x55f92115eb44 [83 3d f9 ef 1d 00 01 0f]: run_poll_loop+0x124/0x3d4
  | 0x55f92115efc9 [48 8b 1d d0 94 12 00 4c]: main+0x108339
  | 0x55f9210589ff [31 c0 e8 ba a6 16 00 31]: main+0x1d6f/0x296a

I'm not sure why it happens. I suspect that it happens because of
session_new() in peer_session_create() that creates another task on the
current thread. If a session task tries to wake up a peer applet task then
it would explain the stack trace, however I've failed to fully understand
the "flow" between applet and session (and how/when task_queue is called in
this flow). I would appreciate any help or tips on how to proceed.

Kind regards,

pt., 1 kwi 2022 o 14:34 Willy Tarreau  napisał(a):

> On Fri, Apr 01, 2022 at 11:23:34AM +0200, Maciej Zdeb wrote:
> > > I remember mentioning something about trying to change this in the
> future.
> > > For outgoing connections I think we could try to figure where peers
> > > connections are and always use one least represented thread.
> > >
> > If I understand the code correctly, the peer_session_create() function
> > creates appctx by appctx_new() which allocates all outgoing connections
> on
> > the current thread "appctx->t = task_new_here();"?
> > So changing peer_session_create() into:
> >
> > static struct appctx *peer_session_create(struct peers *peers, struct
> peer
> > *peer, int thread) {
> > ...
> > appctx = appctx_new_on(&peer_applet, thread);
> > if (!appctx)
> > goto out_close;
> > ...
> > }
> >
> > where appctx_new_on() is a new function that creates an applet on a
> > specified thread would fix my issue? I'm worrying it's not that easy and
> > some locking here and there might be needed. ;-)
>
> Indeed, I think it would work without problems! In this case you could
> even add an array of MAXTHREADS to the peers struct to count the number
> of applets per thread, then peer_session_create() could just scan the
> threads to find the least loaded one and use this one. This would easily
> do the job and sounds simple and efficient enough to get into 2.6.
>
> Please, if you go that way, think about splitting your work in at least
> 3 patches:
>   - 1 for appctx_new_on()
>   - 1 to maintain the applet count per peers struct
>   - 1 to use that counter to start the applet on the best thread
>
> You may find that you need to implement more stuff, but you get the idea.
>
> thanks,
> Willy
>


0001-MINOR-applet-Add-function-to-create-applet-on-select.patch
Description: Binary data


0002-MINOR-peers-Track-number-of-applets-run-by-thread.patch
Description: Binary data


0003-MINOR-peers-Balance-applets-across-threads.patch
Description: Binary data


Re: Peers using heavily single cpu core

2022-04-01 Thread Willy Tarreau
On Fri, Apr 01, 2022 at 11:23:34AM +0200, Maciej Zdeb wrote:
> > I remember mentioning something about trying to change this in the future.
> > For outgoing connections I think we could try to figure where peers
> > connections are and always use one least represented thread.
> >
> If I understand the code correctly, the peer_session_create() function
> creates appctx by appctx_new() which allocates all outgoing connections on
> the current thread "appctx->t = task_new_here();"?
> So changing peer_session_create() into:
> 
> static struct appctx *peer_session_create(struct peers *peers, struct peer
> *peer, int thread) {
> ...
> appctx = appctx_new_on(&peer_applet, thread);
> if (!appctx)
> goto out_close;
> ...
> }
> 
> where appctx_new_on() is a new function that creates an applet on a
> specified thread would fix my issue? I'm worrying it's not that easy and
> some locking here and there might be needed. ;-)

Indeed, I think it would work without problems! In this case you could
even add an array of MAXTHREADS to the peers struct to count the number
of applets per thread, then peer_session_create() could just scan the
threads to find the least loaded one and use this one. This would easily
do the job and sounds simple and efficient enough to get into 2.6.

Please, if you go that way, think about splitting your work in at least
3 patches:
  - 1 for appctx_new_on()
  - 1 to maintain the applet count per peers struct
  - 1 to use that counter to start the applet on the best thread

You may find that you need to implement more stuff, but you get the idea.

thanks,
Willy



Re: Peers using heavily single cpu core

2022-04-01 Thread Maciej Zdeb
pt., 1 kwi 2022 o 09:06 Willy Tarreau  napisał(a):

> I seem to remember a discussion about this in the past and that the
> conclusion basically was that outgoing connections are sent on the
> "current" thread when the management task creates them, while incoming
> connections are balanced depending on the overall process' load.

Yes, that's what I'm observing. High cpu usage is caused by outgoing
connections (visible on "show fd" dump - rport=1024) and currently I don't
mind the incoming ones because they are balanced pretty well.


> I remember mentioning something about trying to change this in the future.
> For outgoing connections I think we could try to figure where peers
> connections are and always use one least represented thread.
>
If I understand the code correctly, the peer_session_create() function
creates appctx by appctx_new() which allocates all outgoing connections on
the current thread "appctx->t = task_new_here();"?
So changing peer_session_create() into:

static struct appctx *peer_session_create(struct peers *peers, struct peer
*peer, int thread) {
...
appctx = appctx_new_on(&peer_applet, thread);
if (!appctx)
goto out_close;
...
}

where appctx_new_on() is a new function that creates an applet on a
specified thread would fix my issue? I'm worrying it's not that easy and
some locking here and there might be needed. ;-)

Kind regards,
Maciej



> Willy
>


Re: Peers using heavily single cpu core

2022-04-01 Thread Willy Tarreau
On Fri, Apr 01, 2022 at 08:58:43AM +0200, Maciej Zdeb wrote:
> Hi Willy,
> Thanks for the patch! Now I'll be able to rebalance peers connections
> manually. Do you know why so many of them are landing on the same thread?

I seem to remember a discussion about this in the past and that the
conclusion basically was that outgoing connections are sent on the
"current" thread when the management task creates them, while incoming
connections are balanced depending on the overall process' load. I
remember mentioning something about trying to change this in the future.
For outgoing connections I think we could try to figure where peers
connections are and always use one least represented thread. For incoming
ones it could be a bit trickier because it would require to implement an
incoming load-balancing mechanism that is specific to the listener. That
wouldn't be stupid in the end, given that we already had to do something
specific for QUIC (disable inbound balancing). The difficulty with the
peers is that an incoming connection may replace an existing one and we
can't know which one. But given that peers connections do not need to
deal with high rates and that there are often more threads than
connections, we could very well use a max-accept 1 on these ones and
carefully scan all threads for peers connections to spot the best one.

Willy



Re: Peers using heavily single cpu core

2022-03-31 Thread Maciej Zdeb
Hi Willy,
Thanks for the patch! Now I'll be able to rebalance peers connections
manually. Do you know why so many of them are landing on the same thread?

Kind regards

czw., 31 mar 2022 o 15:16 Willy Tarreau  napisał(a):

> On Thu, Mar 31, 2022 at 11:56:13AM +0200, Willy Tarreau wrote:
> > > I've made some "session shutdown" tests. With simple configuration
> > > (attached) it is very easy to reproduce a situation when "shutdown
> session"
> > > works only for the first time.
> >
> > Indeed, thanks for this, I can as well reproduce it. With a bit of luck
> > I'll figure what's happening, hoping I won't unearth an ugly bug!
>
> Now found and fixed. It's been bogus since we've split the list of streams
> to be per-thread in 2.4, patch attached if you need it.
>
> Thanks,
> Willy
>


Re: Peers using heavily single cpu core

2022-03-31 Thread Willy Tarreau
On Thu, Mar 31, 2022 at 11:56:13AM +0200, Willy Tarreau wrote:
> > I've made some "session shutdown" tests. With simple configuration
> > (attached) it is very easy to reproduce a situation when "shutdown session"
> > works only for the first time.
> 
> Indeed, thanks for this, I can as well reproduce it. With a bit of luck
> I'll figure what's happening, hoping I won't unearth an ugly bug!

Now found and fixed. It's been bogus since we've split the list of streams
to be per-thread in 2.4, patch attached if you need it.

Thanks,
Willy
>From c40c407268190e41d7d0238e3e2b7669147df9f7 Mon Sep 17 00:00:00 2001
From: Willy Tarreau 
Date: Thu, 31 Mar 2022 14:49:45 +0200
Subject: BUG/MINOR: cli/stream: fix "shutdown session" to iterate over all
 threads

The list of streams was modified in 2.4 to become per-thread with commit
a698eb673 ("MINOR: streams: use one list per stream instead of a global
one"). However the change applied to cli_parse_shutdown_session() is
wrong, as it uses the nullity of the stream pointer to continue on next
threads, but this one is not null once the list_for_each_entry() loop
is finished, it points to the list's head again, so the loop doesn't
check other threads, and no message is printed either to say that the
stream was not found.

Instead we should check if the stream is equal to the requested pointer
since this is the condition to break out of the loop.

Thus must be backported to 2.4. Thanks to Maciej Zdeb for reporting this.
---
 src/stream.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/stream.c b/src/stream.c
index 8acce8075..fd8dada12 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -3750,16 +3750,16 @@ static int cli_parse_shutdown_session(char **args, char 
*payload, struct appctx
if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
return 1;
 
-   if (!*args[2])
-   return cli_err(appctx, "Session pointer expected (use 'show 
sess').\n");
-
ptr = (void *)strtoul(args[2], NULL, 0);
+   if (!ptr)
+   return cli_err(appctx, "Session pointer expected (use 'show 
sess').\n");
+
strm = NULL;
 
thread_isolate();
 
/* first, look for the requested stream in the stream table */
-   for (thr = 0; !strm && thr < global.nbthread; thr++) {
+   for (thr = 0; strm != ptr && thr < global.nbthread; thr++) {
list_for_each_entry(strm, &ha_thread_ctx[thr].streams, list) {
if (strm == ptr) {
stream_shutdown(strm, SF_ERR_KILLED);
@@ -3771,7 +3771,7 @@ static int cli_parse_shutdown_session(char **args, char 
*payload, struct appctx
thread_release();
 
/* do we have the stream ? */
-   if (!strm)
+   if (strm != ptr)
return cli_err(appctx, "No such session (use 'show sess').\n");
 
return 1;
-- 
2.35.1



Re: Peers using heavily single cpu core

2022-03-31 Thread Willy Tarreau
Hi Maciej,

On Wed, Mar 16, 2022 at 12:21:59PM +0100, Maciej Zdeb wrote:
> Hi Willy,
> did you find anything?

I forgot about it after switching to plenty of other topics since :-(

> I've made some "session shutdown" tests. With simple configuration
> (attached) it is very easy to reproduce a situation when "shutdown session"
> works only for the first time.

Indeed, thanks for this, I can as well reproduce it. With a bit of luck
I'll figure what's happening, hoping I won't unearth an ugly bug!

Willy



Re: Peers using heavily single cpu core

2022-03-16 Thread Maciej Zdeb
Hi Willy,
did you find anything?

I've made some "session shutdown" tests. With simple configuration
(attached) it is very easy to reproduce a situation when "shutdown session"
works only for the first time.

1. Kill haproxy to have a clean start:
root@hap-rnd-1a:/etc/haproxy# killall haproxy

2. Show current sessions:
root@hap-rnd-1a:/etc/haproxy# echo "show sess" | socat
unix-connect:/var/run/haproxy/haproxy1.sock stdio
0x562291719560: proto=tcpv4 src=10.0.0.3:5276 fe=hap-rnd-1a be=hap-rnd-1a
srv= ts=00 epoch=0 age=4s calls=1 rate=0 cpu=0 lat=0
rq[f=c48202h,i=0,an=00h,rx=,wx=,ax=] rp[f=80048202h,i=0,an=00h,rx=,wx=,ax=]
s0=[8,200048h,fd=29,ex=] s1=[8,204058h,fd=-1,ex=] exp=
0x562291719fa0: proto=unix_stream src=unix:1 fe=GLOBAL be= srv=
ts=00 epoch=0 age=0s calls=2 rate=2 cpu=0 lat=0
rq[f=c0c020h,i=0,an=00h,rx=,wx=,ax=] rp[f=80008002h,i=0,an=00h,rx=,wx=,ax=]
s0=[8,280008h,fd=30,ex=] s1=[8,204018h,fd=-1,ex=] exp=30s

3. Kill peer session 0x562291719560
root@hap-rnd-1a:/etc/haproxy# echo "shutdown session 0x562291719560" |
socat unix-connect:/var/run/haproxy/haproxy1.sock stdio

4. Show current sessions - confirm peer connection shutdown
root@hap-rnd-1a:/etc/haproxy# echo "show sess" | socat
unix-connect:/var/run/haproxy/haproxy1.sock stdio
0x7f2628026220: proto=unix_stream src=unix:1 fe=GLOBAL be= srv=
ts=00 epoch=0x1 age=0s calls=1 rate=1 cpu=0 lat=0
rq[f=c08000h,i=0,an=00h,rx=,wx=,ax=] rp[f=80008000h,i=0,an=00h,rx=,wx=,ax=]
s0=[8,240008h,fd=29,ex=] s1=[8,204018h,fd=-1,ex=] exp=

5. Show current sessions - confirm new peer connection (note that new
connection has same id 0x7f2628026220 as unix_stream in previous output,
but it is probably by chance)
root@hap-rnd-1a:/etc/haproxy# echo "show sess" | socat
unix-connect:/var/run/haproxy/haproxy1.sock stdio
0x7f2628026220: proto=tcpv4 src=10.0.0.3:5288 fe=hap-rnd-1a be=hap-rnd-1a
srv= ts=00 epoch=0x2 age=3s calls=1 rate=0 cpu=0 lat=0
rq[f=c48200h,i=0,an=00h,rx=,wx=,ax=] rp[f=80048202h,i=0,an=00h,rx=,wx=,ax=]
s0=[8,200048h,fd=29,ex=] s1=[8,204058h,fd=-1,ex=] exp=
0x7f263c026220: proto=unix_stream src=unix:1 fe=GLOBAL be= srv=
ts=00 epoch=0x2 age=0s calls=1 rate=1 cpu=0 lat=0
rq[f=c08000h,i=0,an=00h,rx=,wx=,ax=] rp[f=80008002h,i=0,an=00h,rx=,wx=,ax=]
s0=[8,240008h,fd=30,ex=] s1=[8,204018h,fd=-1,ex=] exp=

6. Again kill peer session 0x7f2628026220
root@hap-rnd-1a:/etc/haproxy# echo "shutdown session 0x7f2628026220" |
socat unix-connect:/var/run/haproxy/haproxy1.sock stdio

7. Show current sessions - note that 0x7f2628026220 was not killed in the
previous step
root@hap-rnd-1a:/etc/haproxy# echo "show sess" | socat
unix-connect:/var/run/haproxy/haproxy1.sock stdio
0x7f267c026a60: proto=unix_stream src=unix:1 fe=GLOBAL be= srv=
ts=00 epoch=0x3 age=0s calls=1 rate=1 cpu=0 lat=0
rq[f=c08000h,i=0,an=00h,rx=,wx=,ax=] rp[f=80008000h,i=0,an=00h,rx=,wx=,ax=]
s0=[8,240008h,fd=30,ex=] s1=[8,204018h,fd=-1,ex=] exp=
0x7f2628026220: proto=tcpv4 src=10.0.0.3:5288 fe=hap-rnd-1a be=hap-rnd-1a
srv= ts=00 epoch=0x2 age=17s calls=1 rate=0 cpu=0 lat=0
rq[f=c48202h,i=0,an=00h,rx=,wx=,ax=] rp[f=80048202h,i=0,an=00h,rx=,wx=,ax=]
s0=[8,200048h,fd=29,ex=] s1=[8,204058h,fd=-1,ex=] exp=

8. Kill peer session 0x7f2628026220
root@hap-rnd-1a:/etc/haproxy# echo "shutdown session 0x7f2628026220" |
socat unix-connect:/var/run/haproxy/haproxy1.sock stdio

9. Show session - again no effect
root@hap-rnd-1a:/etc/haproxy# echo "show sess" | socat
unix-connect:/var/run/haproxy/haproxy1.sock stdio
0x7f2628026220: proto=tcpv4 src=10.0.0.3:5288 fe=hap-rnd-1a be=hap-rnd-1a
srv= ts=00 epoch=0x2 age=22s calls=1 rate=0 cpu=0 lat=0
rq[f=c48202h,i=0,an=00h,rx=,wx=,ax=] rp[f=80048202h,i=0,an=00h,rx=,wx=,ax=]
s0=[8,200048h,fd=29,ex=] s1=[8,204058h,fd=-1,ex=] exp=
0x7f261c026220: proto=unix_stream src=unix:1 fe=GLOBAL be= srv=
ts=00 epoch=0x4 age=0s calls=1 rate=1 cpu=0 lat=0
rq[f=c08000h,i=0,an=00h,rx=,wx=,ax=] rp[f=80008002h,i=0,an=00h,rx=,wx=,ax=]
s0=[8,240008h,fd=30,ex=] s1=[8,204018h,fd=-1,ex=] exp=

Kind regards,

sob., 12 mar 2022 o 00:20 Willy Tarreau  napisał(a):

> On Fri, Mar 11, 2022 at 10:19:09PM +0100, Maciej Zdeb wrote:
> > Hi Willy,
> >
> > Thank you for such useful info! I've checked the worst HAProxy nodes and
> on
> > every such node all outgoing peers connections are run on the same
> thread:
> (...)
> Indeed. I was pretty sure we were setting them to any thread on creation
> but maybe I'm wrong, I'll have to recheck.
>
> > On one node I was able to rebalance it, but on the node above (and other
> > nodes) I'm not able to shutdown the sessions:
> (...)
> > echo "shutdown session 0x7f0aa402e2c0" | socat
> > unix-connect:/var/run/haproxy.sock stdio
> >
> > echo "show sess 0x7f0aa402e2c0" | socat
> unix-connect:/var/run/haproxy.sock
> > stdio
> > 0x7f0aa402e2c0: [11/Mar/2022:07:17:02.313221] id=0 proto=?
> (...)
>
> That's not expected, another thing I'll have to check.
>
> Thanks for testing. I'll put that in pause for the week-end, though :-)
>
> cheers,
> Willy
>
global
chroot /var/lib/h

Re: Peers using heavily single cpu core

2022-03-11 Thread Willy Tarreau
On Fri, Mar 11, 2022 at 10:19:09PM +0100, Maciej Zdeb wrote:
> Hi Willy,
> 
> Thank you for such useful info! I've checked the worst HAProxy nodes and on
> every such node all outgoing peers connections are run on the same thread:
(...)
Indeed. I was pretty sure we were setting them to any thread on creation
but maybe I'm wrong, I'll have to recheck.

> On one node I was able to rebalance it, but on the node above (and other
> nodes) I'm not able to shutdown the sessions:
(...)
> echo "shutdown session 0x7f0aa402e2c0" | socat
> unix-connect:/var/run/haproxy.sock stdio
> 
> echo "show sess 0x7f0aa402e2c0" | socat unix-connect:/var/run/haproxy.sock
> stdio
> 0x7f0aa402e2c0: [11/Mar/2022:07:17:02.313221] id=0 proto=?
(...)

That's not expected, another thing I'll have to check.

Thanks for testing. I'll put that in pause for the week-end, though :-)

cheers,
Willy



Re: Peers using heavily single cpu core

2022-03-11 Thread Maciej Zdeb
Hi Willy,

Thank you for such useful info! I've checked the worst HAProxy nodes and on
every such node all outgoing peers connections are run on the same thread:

echo "show fd" | socat unix-connect:/var/run/haproxy.sock stdio | grep "px="
430 : st=0x010121(cL heopI W:sRa R:srA) tmask=0x40 umask=0x0
owner=0x7f0aa4039250 iocb=0x564c0df95f40(sock_conn_iocb) back=1
cflg=0x10002300 fam=ipv4 lport=22850 rport=1024 px=hap. mux=PASS
ctx=0x7f0aa4039450 xprt=RAW
500 : st=0x010121(cL heopI W:sRa R:srA) tmask=0x40 umask=0x0
owner=0x7f0aa403d4e0 iocb=0x564c0df95f40(sock_conn_iocb) back=1
cflg=0x10002300 fam=ipv4 lport=58906 rport=1024 px=hap mux=PASS
ctx=0x7f0aa403d6e0 xprt=RAW
501 : st=0x010121(cL heopI W:sRa R:srA) tmask=0x40 umask=0x0
owner=0x7f0aa4041770 iocb=0x564c0df95f40(sock_conn_iocb) back=1
cflg=0x10002300 fam=ipv4 lport=54470 rport=1024 px=hap mux=PASS
ctx=0x7f0aa4041970 xprt=RAW
502 : st=0x010121(cL heopI W:sRa R:srA) tmask=0x40 umask=0x0
owner=0x7f0aa4045a00 iocb=0x564c0df95f40(sock_conn_iocb) back=1
cflg=0x10002300 fam=ipv4 lport=48926 rport=1024 px=hap mux=PASS
ctx=0x7f0aa4045c00 xprt=RAW
503 : st=0x010121(cL heopI W:sRa R:srA) tmask=0x40 umask=0x0
owner=0x7f0aa4049c90 iocb=0x564c0df95f40(sock_conn_iocb) back=1
cflg=0x10002300 fam=ipv4 lport=21468 rport=1024 px=hap mux=PASS
ctx=0x7f0aa4049e90 xprt=RAW

echo "show sess" | socat unix-connect:/var/run/haproxy.sock stdio | grep
"proto=?" | grep "epoch=0 " | grep 14h
0x7f0aa402e2c0: proto=? ts=00 epoch=0 age=14h53m calls=10724 rate=1 cpu=0
lat=0 rq[f=848202h,i=0,an=00h,rx=5s,wx=,ax=]
rp[f=80448202h,i=0,an=00h,rx=,wx=,ax=] s0=[8,204048h,fd=-1,ex=]
s1=[8,2000d8h,fd=430,ex=] exp=3s
0x7f0aa402ece0: proto=? ts=00 epoch=0 age=14h53m calls=10724 rate=1 cpu=0
lat=0 rq[f=848202h,i=0,an=00h,rx=5s,wx=,ax=]
rp[f=80448202h,i=0,an=00h,rx=,wx=,ax=] s0=[8,204048h,fd=-1,ex=]
s1=[8,2000d8h,fd=500,ex=] exp=3s
0x7f0aa402f700: proto=? ts=00 epoch=0 age=14h53m calls=10724 rate=1 cpu=0
lat=0 rq[f=848202h,i=0,an=00h,rx=5s,wx=,ax=]
rp[f=80448202h,i=0,an=00h,rx=,wx=,ax=] s0=[8,204048h,fd=-1,ex=]
s1=[8,2000d8h,fd=501,ex=] exp=3s
0x7f0aa4030120: proto=? ts=00 epoch=0 age=14h53m calls=10722 rate=0 cpu=0
lat=0 rq[f=848202h,i=0,an=00h,rx=5s,wx=,ax=]
rp[f=80448202h,i=0,an=00h,rx=,wx=,ax=] s0=[8,204048h,fd=-1,ex=]
s1=[8,2000d8h,fd=502,ex=] exp=2s
0x7f0aa4030b40: proto=? ts=00 epoch=0 age=14h53m calls=10724 rate=1 cpu=0
lat=0 rq[f=848202h,i=0,an=00h,rx=5s,wx=,ax=]
rp[f=80448202h,i=0,an=00h,rx=,wx=,ax=] s0=[8,204048h,fd=-1,ex=]
s1=[8,2000d8h,fd=503,ex=] exp=3s

On one node I was able to rebalance it, but on the node above (and other
nodes) I'm not able to shutdown the sessions:
echo "show sess 0x7f0aa402e2c0" | socat unix-connect:/var/run/haproxy.sock
stdio
0x7f0aa402e2c0: [11/Mar/2022:07:17:02.313221] id=0 proto=?
  flags=0x6, conn_retries=3, srv_conn=(nil), pend_pos=(nil) waiting=0
epoch=0
  frontend=x (id=4294967295 mode=http), listener=? (id=0)
  backend=x (id=4294967295 mode=http) addr=x:22850
  server= (id=0) addr=y:1024
  task=0x7f0aa402e7d0 (state=0x00 nice=0 calls=10741 rate=0 exp=1s
tmask=0x40 age=14h54m)
  si[0]=0x7f0aa402e600 (state=EST flags=0x204048
endp0=APPCTX:0x7f0aa402df90 exp= et=0x000 sub=0)
  si[1]=0x7f0aa402e658 (state=EST flags=0x2000d8 endp1=CS:0x7f0aa4039400
exp= et=0x000 sub=1)
  app0=0x7f0aa402df90 st0=7 st1=0 st2=0 applet= tmask=0x40 nice=0
calls=206051832 rate=2860 cpu=0 lat=0
  co1=0x7f0aa4039250 ctrl=tcpv4 xprt=RAW mux=PASS data=STRM
target=PROXY:0x564c0ff53760
  flags=0x10003300 fd=430 fd.state=10121 updt=0 fd.tmask=0x40
  cs=0x7f0aa4039400 csf=0x8200 ctx=(nil)
  req=0x7f0aa402e2d0 (f=0x848202 an=0x0 pipe=0 tofwd=-1 total=9489764648)
  an_exp= rex=4s wex=
  buf=0x7f0aa402e2d8 data=(nil) o=0 p=0 i=0 size=0
  res=0x7f0aa402e330 (f=0x80448202 an=0x0 pipe=0 tofwd=-1 total=9320288685)
  an_exp= rex= wex=
  buf=0x7f0aa402e338 data=(nil) o=0 p=0 i=0 size=0

echo "shutdown session 0x7f0aa402e2c0" | socat
unix-connect:/var/run/haproxy.sock stdio

echo "show sess 0x7f0aa402e2c0" | socat unix-connect:/var/run/haproxy.sock
stdio
0x7f0aa402e2c0: [11/Mar/2022:07:17:02.313221] id=0 proto=?
  flags=0x6, conn_retries=3, srv_conn=(nil), pend_pos=(nil) waiting=0
epoch=0
  frontend=x (id=4294967295 mode=http), listener=? (id=0)
  backend=x (id=4294967295 mode=http) addr=x:22850
  server= (id=0) addr=x:1024
  task=0x7f0aa402e7d0 (state=0x00 nice=0 calls=10745 rate=1 exp=4s
tmask=0x40 age=14h55m)
  si[0]=0x7f0aa402e600 (state=EST flags=0x204048
endp0=APPCTX:0x7f0aa402df90 exp= et=0x000 sub=0)
  si[1]=0x7f0aa402e658 (state=EST flags=0x2000d8 endp1=CS:0x7f0aa4039400
exp= et=0x000 sub=1)
  app0=0x7f0aa402df90 st0=7 st1=0 st2=0 applet= tmask=0x40 nice=0
calls=206100614 rate=3160 cpu=0 lat=0
  co1=0x7f0aa4039250 ctrl=tcpv4 xprt=RAW mux=PASS data=STRM
target=PROXY:0x564c0ff53760
  flags=0x10003300 fd=430 fd.state=10121 updt=0 fd.tmask=0x40
  cs=0x7f0aa4039400 csf=0x8200 ctx=(nil)
  req=0x7f0aa402e2d0 (f=0x848202 an=0x0 pipe=0 tofwd=-1 total=94919611

Re: Peers using heavily single cpu core

2022-03-11 Thread Willy Tarreau
Hi Maciej,

On Fri, Mar 04, 2022 at 01:10:37PM +0100, Maciej Zdeb wrote:
> Hi,
> 
> I'm experiencing high CPU usage on a single core, idle drops below 40%
> while other cores are at 80% idle. Peers cluster is quite big (12 servers,
> each server running 12 threads) and is used for synchronization of 3
> stick-tables of 1 million entries size.
> 
> Is peers protocol single threaded and high usage on single core is expected
> or am I experiencing some kind of bug? I'll keep digging to be sure nothing
> else from my configuration is causing the  issue.

Almost. More precisely, each peers connection runs on a single thread
at once (like any connection). Some such connections may experience
heavy protocol parsing so it may be possible that sometimes you end up
with an unbalance number of connections on threads. It's tricky though,
because we could imagine a mechanism to try to evenly spread the outgoing
peers connection on threads but the incoming ones will land where they
land.

That's something you can check with "show sess" and/or "show fd", looking
for those related to your peers and checking their thread_mask. If you
find two on the same thread (same thread_mask), you can shut one of them
down using "shutdown session " and it will reconnect, possibly on
another thread. That could confirm that it's the root cause of the
problem you're experiencing.

I'm wondering if we shouldn't introduce a notion of "heavy connection"
like we already have heavy tasks for the scheduler. These ones would
be balanced differently from others. Usually they're long-lived and
can eat massive amounts of CPU so it would make sense. The only ones
I'm thinking about are the peers ones but the concept would be more
portable than focusing on peers. Usually such long connections are not
refreshed often so we probably prefer to spend time carefully picking
the best thread rather than saving 200ns of processing and having to
pay it for the whole connection's life time.

Willy



Peers using heavily single cpu core

2022-03-04 Thread Maciej Zdeb
Hi,

I'm experiencing high CPU usage on a single core, idle drops below 40%
while other cores are at 80% idle. Peers cluster is quite big (12 servers,
each server running 12 threads) and is used for synchronization of 3
stick-tables of 1 million entries size.

Is peers protocol single threaded and high usage on single core is expected
or am I experiencing some kind of bug? I'll keep digging to be sure nothing
else from my configuration is causing the  issue.

haproxy -v
HAProxy version 2.4.14-eaa786f 2022/02/25 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2
2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.14.html
Running on: Linux 4.15.0-154-generic #161-Ubuntu SMP Fri Jul 30 13:04:17
UTC 2021 x86_64

Kind regards,
Maciej Zdeb