mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
net/tls: add a TX lock
TLS TX needs to release and re-acquire the socket lock if send buffer
fills up.
TLS SW TX path currently depends on only allowing one thread to enter
the function by the abuse of sk_write_pending. If another writer is
already waiting for memory no new ones are allowed in.
This has two problems:
- writers don't wake other threads up when they leave the kernel;
meaning that this scheme works for single extra thread (second
application thread or delayed work) because memory becoming
available will send a wake up request, but as Mallesham and
Pooja report with larger number of threads it leads to threads
being put to sleep indefinitely;
- the delayed work does not get _scheduled_ but it may _run_ when
other writers are present leading to crashes as writers don't
expect state to change under their feet (same records get pushed
and freed multiple times); it's hard to reliably bail from the
work, however, because the mere presence of a writer does not
guarantee that the writer will push pending records before exiting.
Ensuring wakeups always happen will make the code basically open
code a mutex. Just use a mutex.
The TLS HW TX path does not have any locking (not even the
sk_write_pending hack), yet it uses a per-socket sg_tx_data
array to push records.
Fixes: a42055e8d2
("net/tls: Add support for async encryption of records for performance")
Reported-by: Mallesham Jatharakonda <mallesh537@gmail.com>
Reported-by: Pooja Trivedi <poojatrivedi@gmail.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
02b1fa07bb
commit
79ffe6087e
4 changed files with 20 additions and 14 deletions
|
@ -523,8 +523,10 @@ last_record:
|
|||
int tls_device_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
|
||||
{
|
||||
unsigned char record_type = TLS_RECORD_TYPE_DATA;
|
||||
struct tls_context *tls_ctx = tls_get_ctx(sk);
|
||||
int rc;
|
||||
|
||||
mutex_lock(&tls_ctx->tx_lock);
|
||||
lock_sock(sk);
|
||||
|
||||
if (unlikely(msg->msg_controllen)) {
|
||||
|
@ -538,12 +540,14 @@ int tls_device_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
|
|||
|
||||
out:
|
||||
release_sock(sk);
|
||||
mutex_unlock(&tls_ctx->tx_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int tls_device_sendpage(struct sock *sk, struct page *page,
|
||||
int offset, size_t size, int flags)
|
||||
{
|
||||
struct tls_context *tls_ctx = tls_get_ctx(sk);
|
||||
struct iov_iter msg_iter;
|
||||
char *kaddr = kmap(page);
|
||||
struct kvec iov;
|
||||
|
@ -552,6 +556,7 @@ int tls_device_sendpage(struct sock *sk, struct page *page,
|
|||
if (flags & MSG_SENDPAGE_NOTLAST)
|
||||
flags |= MSG_MORE;
|
||||
|
||||
mutex_lock(&tls_ctx->tx_lock);
|
||||
lock_sock(sk);
|
||||
|
||||
if (flags & MSG_OOB) {
|
||||
|
@ -568,6 +573,7 @@ int tls_device_sendpage(struct sock *sk, struct page *page,
|
|||
|
||||
out:
|
||||
release_sock(sk);
|
||||
mutex_unlock(&tls_ctx->tx_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue