All of lore.kernel.org
 help / color / mirror / Atom feed
* sk_data_ready callback restore
@ 2023-03-16 11:26 Hannes Reinecke
  2023-03-16 13:35 ` Chuck Lever III
  0 siblings, 1 reply; 4+ messages in thread
From: Hannes Reinecke @ 2023-03-16 11:26 UTC (permalink / raw)
  To: Chuck Lever; +Cc: kernel-tls-handshake

Hi Chuck,

some good news; my prototype is up and running and seems to be happy 
with the infrastructure:

nvme nvme0: connecting queue 0
nvme nvme0: queue 0: start TLS with key 389e6cd5 keyring 23836d8b
nvmet_tcp: queue 0 hdr type 22 hlen 1 plen 33554719 size 128
nvmet_tcp: queue 0: TLS ServerHello
nvmet_tcp: queue 0 wakeup userspace
nvme nvme0: queue 0: TLS handshake done, key 389e6cd5, status 0
nvmet_tcp: queue 0: TLS handshake done, key 389e6cd5, status 0

but there's one question: in order to get this to work I had to
set the sk_data_ready() callback before starting the TLS handshake.

queue->data_ready = sk->sk_data_ready;
sk->sk_data_ready = nvmet_tcp_tls_data_ready;

That works, but it's getting tricky once the TLS handshake is done.
Naively I would have thought that I need to reset the sk_data_ready()
callback

sk->sk_data_ready = queue->data_ready;
queue->data_ready = NULL;

But as I'm paranoid I've check whether I'll be resetting the correct
sk_data_ready() callback:

WARN_ON(sk->sk_data_ready != nvmet_tcp_tls_data_ready);

before resetting.
And, surprise, surprise, that WARN_ON triggers.
Probably understandable, as kTLS is changing the callbacks, too.

Leaving the question: how do I _disable_ my sk_data_ready() callback?
Just blindly reassigning the original callback clearly is not a good 
idea, but doing nothing would mean that my callback will be left in 
place during the entire connection, which also is not a good idea.
So what is the correct way of disabling the callback?

Cheers,

Hannes

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: sk_data_ready callback restore
  2023-03-16 11:26 sk_data_ready callback restore Hannes Reinecke
@ 2023-03-16 13:35 ` Chuck Lever III
  2023-03-16 13:40   ` Hannes Reinecke
  0 siblings, 1 reply; 4+ messages in thread
From: Chuck Lever III @ 2023-03-16 13:35 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: kernel-tls-handshake



> On Mar 16, 2023, at 7:26 AM, Hannes Reinecke <hare@suse.de> wrote:
> 
> Hi Chuck,
> 
> some good news; my prototype is up and running and seems to be happy with the infrastructure:
> 
> nvme nvme0: connecting queue 0
> nvme nvme0: queue 0: start TLS with key 389e6cd5 keyring 23836d8b
> nvmet_tcp: queue 0 hdr type 22 hlen 1 plen 33554719 size 128
> nvmet_tcp: queue 0: TLS ServerHello
> nvmet_tcp: queue 0 wakeup userspace
> nvme nvme0: queue 0: TLS handshake done, key 389e6cd5, status 0
> nvmet_tcp: queue 0: TLS handshake done, key 389e6cd5, status 0
> 
> but there's one question: in order to get this to work I had to
> set the sk_data_ready() callback before starting the TLS handshake.
> 
> queue->data_ready = sk->sk_data_ready;
> sk->sk_data_ready = nvmet_tcp_tls_data_ready;
> 
> That works, but it's getting tricky once the TLS handshake is done.
> Naively I would have thought that I need to reset the sk_data_ready()
> callback
> 
> sk->sk_data_ready = queue->data_ready;
> queue->data_ready = NULL;
> 
> But as I'm paranoid I've check whether I'll be resetting the correct
> sk_data_ready() callback:
> 
> WARN_ON(sk->sk_data_ready != nvmet_tcp_tls_data_ready);
> 
> before resetting.
> And, surprise, surprise, that WARN_ON triggers.
> Probably understandable, as kTLS is changing the callbacks, too.

Socket callbacks form a chain. Each module wanting a callback
saves the callback function value, then updates the socket's
callback function pointer to point to its callback.

Then, when it's data_ready callback function is invoked, it
calls the saved callback function first, then does whatever
it needs to do, and returns.


> Leaving the question: how do I _disable_ my sk_data_ready() callback?
> Just blindly reassigning the original callback clearly is not a good idea, but doing nothing would mean that my callback will be left in place during the entire connection, which also is not a good idea.
> So what is the correct way of disabling the callback?

The way I've done it is to add an atomic flag that is set
only during handshakes. When RPC's sk_data_ready callback
function is called, if that flag is set, just call the
saved callback and then return immediately without
doing any RPC receive processing.

Here's the RPC client side that demonstrates both how
callback chaining works and how I disable the function
during a handshake:

https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git/tree/net/sunrpc/xprtsock.c?h=topic-rpc-with-tls-upcall#n1436


--
Chuck Lever



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: sk_data_ready callback restore
  2023-03-16 13:35 ` Chuck Lever III
@ 2023-03-16 13:40   ` Hannes Reinecke
  2023-03-16 13:43     ` Chuck Lever III
  0 siblings, 1 reply; 4+ messages in thread
From: Hannes Reinecke @ 2023-03-16 13:40 UTC (permalink / raw)
  To: Chuck Lever III; +Cc: kernel-tls-handshake

On 3/16/23 14:35, Chuck Lever III wrote:
> 
> 
>> On Mar 16, 2023, at 7:26 AM, Hannes Reinecke <hare@suse.de> wrote:
>>
>> Hi Chuck,
>>
>> some good news; my prototype is up and running and seems to be happy with the infrastructure:
>>
>> nvme nvme0: connecting queue 0
>> nvme nvme0: queue 0: start TLS with key 389e6cd5 keyring 23836d8b
>> nvmet_tcp: queue 0 hdr type 22 hlen 1 plen 33554719 size 128
>> nvmet_tcp: queue 0: TLS ServerHello
>> nvmet_tcp: queue 0 wakeup userspace
>> nvme nvme0: queue 0: TLS handshake done, key 389e6cd5, status 0
>> nvmet_tcp: queue 0: TLS handshake done, key 389e6cd5, status 0
>>
>> but there's one question: in order to get this to work I had to
>> set the sk_data_ready() callback before starting the TLS handshake.
>>
>> queue->data_ready = sk->sk_data_ready;
>> sk->sk_data_ready = nvmet_tcp_tls_data_ready;
>>
>> That works, but it's getting tricky once the TLS handshake is done.
>> Naively I would have thought that I need to reset the sk_data_ready()
>> callback
>>
>> sk->sk_data_ready = queue->data_ready;
>> queue->data_ready = NULL;
>>
>> But as I'm paranoid I've check whether I'll be resetting the correct
>> sk_data_ready() callback:
>>
>> WARN_ON(sk->sk_data_ready != nvmet_tcp_tls_data_ready);
>>
>> before resetting.
>> And, surprise, surprise, that WARN_ON triggers.
>> Probably understandable, as kTLS is changing the callbacks, too.
> 
> Socket callbacks form a chain. Each module wanting a callback
> saves the callback function value, then updates the socket's
> callback function pointer to point to its callback.
> 
> Then, when it's data_ready callback function is invoked, it
> calls the saved callback function first, then does whatever
> it needs to do, and returns.
> 
Yes, understood; that's what my prototype does.

> 
>> Leaving the question: how do I _disable_ my sk_data_ready() callback?
>> Just blindly reassigning the original callback clearly is not a good idea, but doing nothing would mean that my callback will be left in place during the entire connection, which also is not a good idea.
>> So what is the correct way of disabling the callback?
> 
> The way I've done it is to add an atomic flag that is set
> only during handshakes. When RPC's sk_data_ready callback
> function is called, if that flag is set, just call the
> saved callback and then return immediately without
> doing any RPC receive processing.
> 
Which is what I ended up doing; it felt slightly odd as 'normal' 
programming rules would imply that any action you do should be reverted 
once you're done.
Which doesn't work here, as essentially it's impossible to restore
the callback.

But if that's the way it should be I'm fine.
Just wanted to clarify.

Cheers,

Hannes


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: sk_data_ready callback restore
  2023-03-16 13:40   ` Hannes Reinecke
@ 2023-03-16 13:43     ` Chuck Lever III
  0 siblings, 0 replies; 4+ messages in thread
From: Chuck Lever III @ 2023-03-16 13:43 UTC (permalink / raw)
  To: Hannes Reinecke; +Cc: kernel-tls-handshake



> On Mar 16, 2023, at 9:40 AM, Hannes Reinecke <hare@suse.de> wrote:
> 
> On 3/16/23 14:35, Chuck Lever III wrote:
>>> On Mar 16, 2023, at 7:26 AM, Hannes Reinecke <hare@suse.de> wrote:
>>> 
>>> Hi Chuck,
>>> 
>>> some good news; my prototype is up and running and seems to be happy with the infrastructure:
>>> 
>>> nvme nvme0: connecting queue 0
>>> nvme nvme0: queue 0: start TLS with key 389e6cd5 keyring 23836d8b
>>> nvmet_tcp: queue 0 hdr type 22 hlen 1 plen 33554719 size 128
>>> nvmet_tcp: queue 0: TLS ServerHello
>>> nvmet_tcp: queue 0 wakeup userspace
>>> nvme nvme0: queue 0: TLS handshake done, key 389e6cd5, status 0
>>> nvmet_tcp: queue 0: TLS handshake done, key 389e6cd5, status 0
>>> 
>>> but there's one question: in order to get this to work I had to
>>> set the sk_data_ready() callback before starting the TLS handshake.
>>> 
>>> queue->data_ready = sk->sk_data_ready;
>>> sk->sk_data_ready = nvmet_tcp_tls_data_ready;
>>> 
>>> That works, but it's getting tricky once the TLS handshake is done.
>>> Naively I would have thought that I need to reset the sk_data_ready()
>>> callback
>>> 
>>> sk->sk_data_ready = queue->data_ready;
>>> queue->data_ready = NULL;
>>> 
>>> But as I'm paranoid I've check whether I'll be resetting the correct
>>> sk_data_ready() callback:
>>> 
>>> WARN_ON(sk->sk_data_ready != nvmet_tcp_tls_data_ready);
>>> 
>>> before resetting.
>>> And, surprise, surprise, that WARN_ON triggers.
>>> Probably understandable, as kTLS is changing the callbacks, too.
>> Socket callbacks form a chain. Each module wanting a callback
>> saves the callback function value, then updates the socket's
>> callback function pointer to point to its callback.
>> Then, when it's data_ready callback function is invoked, it
>> calls the saved callback function first, then does whatever
>> it needs to do, and returns.
> Yes, understood; that's what my prototype does.
> 
>>> Leaving the question: how do I _disable_ my sk_data_ready() callback?
>>> Just blindly reassigning the original callback clearly is not a good idea, but doing nothing would mean that my callback will be left in place during the entire connection, which also is not a good idea.
>>> So what is the correct way of disabling the callback?
>> The way I've done it is to add an atomic flag that is set
>> only during handshakes. When RPC's sk_data_ready callback
>> function is called, if that flag is set, just call the
>> saved callback and then return immediately without
>> doing any RPC receive processing.
> Which is what I ended up doing; it felt slightly odd as 'normal' programming rules would imply that any action you do should be reverted once you're done.
> Which doesn't work here, as essentially it's impossible to restore
> the callback.

Changing the callback function addresses while the socket
is in use is racy, and also you have to preserve the callback
chain.


> But if that's the way it should be I'm fine.
> Just wanted to clarify.
> 
> Cheers,
> 
> Hannes

--
Chuck Lever



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-03-16 13:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-16 11:26 sk_data_ready callback restore Hannes Reinecke
2023-03-16 13:35 ` Chuck Lever III
2023-03-16 13:40   ` Hannes Reinecke
2023-03-16 13:43     ` Chuck Lever III

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.