summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2019-09-07 01:29:58 -0400
committerDavid S. Miller <davem@davemloft.net>2019-09-07 12:10:34 -0400
commitd4774ac0d49ae92c5176c9848db555e89a5a4e45 (patch)
treed7368d446e09e07f4fd0ed6060d702dfb961c889
parent7ccd451912dd6407957676ae584248bdadc97b38 (diff)
net/tls: use RCU for the adder to the offload record list
All modifications to TLS record list happen under the socket lock. Since records form an ordered queue readers are only concerned about elements being removed, additions can happen concurrently. Use RCU primitives to ensure the correct access types (READ_ONCE/WRITE_ONCE). Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/tls/tls_device.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
index 285c9f9e94e4..b11355e00514 100644
--- a/net/tls/tls_device.c
+++ b/net/tls/tls_device.c
@@ -280,9 +280,7 @@ static int tls_push_record(struct sock *sk,
280 280
281 tls_append_frag(record, &dummy_tag_frag, prot->tag_size); 281 tls_append_frag(record, &dummy_tag_frag, prot->tag_size);
282 record->end_seq = tp->write_seq + record->len; 282 record->end_seq = tp->write_seq + record->len;
283 spin_lock_irq(&offload_ctx->lock); 283 list_add_tail_rcu(&record->list, &offload_ctx->records_list);
284 list_add_tail(&record->list, &offload_ctx->records_list);
285 spin_unlock_irq(&offload_ctx->lock);
286 offload_ctx->open_record = NULL; 284 offload_ctx->open_record = NULL;
287 285
288 if (test_bit(TLS_TX_SYNC_SCHED, &ctx->flags)) 286 if (test_bit(TLS_TX_SYNC_SCHED, &ctx->flags))
@@ -535,12 +533,16 @@ struct tls_record_info *tls_get_record(struct tls_offload_context_tx *context,
535 /* if retransmit_hint is irrelevant start 533 /* if retransmit_hint is irrelevant start
536 * from the beggining of the list 534 * from the beggining of the list
537 */ 535 */
538 info = list_first_entry(&context->records_list, 536 info = list_first_entry_or_null(&context->records_list,
539 struct tls_record_info, list); 537 struct tls_record_info, list);
538 if (!info)
539 return NULL;
540 record_sn = context->unacked_record_sn; 540 record_sn = context->unacked_record_sn;
541 } 541 }
542 542
543 list_for_each_entry_from(info, &context->records_list, list) { 543 /* We just need the _rcu for the READ_ONCE() */
544 rcu_read_lock();
545 list_for_each_entry_from_rcu(info, &context->records_list, list) {
544 if (before(seq, info->end_seq)) { 546 if (before(seq, info->end_seq)) {
545 if (!context->retransmit_hint || 547 if (!context->retransmit_hint ||
546 after(info->end_seq, 548 after(info->end_seq,
@@ -549,12 +551,15 @@ struct tls_record_info *tls_get_record(struct tls_offload_context_tx *context,
549 context->retransmit_hint = info; 551 context->retransmit_hint = info;
550 } 552 }
551 *p_record_sn = record_sn; 553 *p_record_sn = record_sn;
552 return info; 554 goto exit_rcu_unlock;
553 } 555 }
554 record_sn++; 556 record_sn++;
555 } 557 }
558 info = NULL;
556 559
557 return NULL; 560exit_rcu_unlock:
561 rcu_read_unlock();
562 return info;
558} 563}
559EXPORT_SYMBOL(tls_get_record); 564EXPORT_SYMBOL(tls_get_record);
560 565