Skip to content

Commit 4a8fa51

Browse files
UCS/RCACHE: Use built-in atomics for rwlock
1 parent 27927ed commit 4a8fa51

File tree

4 files changed

+28
-36
lines changed

4 files changed

+28
-36
lines changed

src/ucs/memory/rcache.c

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <ucs/sys/string.h>
2323
#include <ucs/arch/cpu.h>
2424
#include <ucs/type/spinlock.h>
25+
#include <ucs/type/rwlock.h>
2526
#include <ucs/vfs/base/vfs_obj.h>
2627
#include <ucm/api/ucm.h>
2728

@@ -424,7 +425,7 @@ void ucs_mem_region_destroy_internal(ucs_rcache_t *rcache,
424425
UCS_STATS_UPDATE_COUNTER(rcache->stats, UCS_RCACHE_DEREGS, 1);
425426

426427
if (drop_lock) {
427-
pthread_rwlock_unlock(&rcache->pgt_lock);
428+
ucs_rw_spinlock_write_unlock(&rcache->pgt_lock);
428429
}
429430

430431
UCS_PROFILE_NAMED_CALL_VOID_ALWAYS("mem_dereg",
@@ -433,7 +434,7 @@ void ucs_mem_region_destroy_internal(ucs_rcache_t *rcache,
433434
region);
434435

435436
if (drop_lock) {
436-
pthread_rwlock_wrlock(&rcache->pgt_lock);
437+
ucs_rw_spinlock_write_lock(&rcache->pgt_lock);
437438
}
438439
}
439440

@@ -493,14 +494,14 @@ static inline void ucs_rcache_region_put_internal(ucs_rcache_t *rcache,
493494

494495
/* Destroy region and de-register memory */
495496
if (flags & UCS_RCACHE_REGION_PUT_FLAG_TAKE_PGLOCK) {
496-
pthread_rwlock_wrlock(&rcache->pgt_lock);
497+
ucs_rw_spinlock_write_lock(&rcache->pgt_lock);
497498
}
498499

499500
ucs_mem_region_destroy_internal(rcache, region,
500501
flags & UCS_RCACHE_REGION_PUT_FLAG_TAKE_PGLOCK);
501502

502503
if (flags & UCS_RCACHE_REGION_PUT_FLAG_TAKE_PGLOCK) {
503-
pthread_rwlock_unlock(&rcache->pgt_lock);
504+
ucs_rw_spinlock_write_unlock(&rcache->pgt_lock);
504505
}
505506
}
506507

@@ -649,15 +650,15 @@ static void ucs_rcache_unmapped_callback(ucm_event_type_t event_type,
649650
* no rcache operations are performed to clean it.
650651
*/
651652
if (!(rcache->params.flags & UCS_RCACHE_FLAG_SYNC_EVENTS) &&
652-
!pthread_rwlock_trywrlock(&rcache->pgt_lock)) {
653+
ucs_rw_spinlock_write_trylock(&rcache->pgt_lock)) {
653654
/* coverity[double_lock] */
654655
ucs_rcache_invalidate_range(rcache, start, end,
655656
UCS_RCACHE_REGION_PUT_FLAG_ADD_TO_GC);
656657
UCS_STATS_UPDATE_COUNTER(rcache->stats, UCS_RCACHE_UNMAPS, 1);
657658
/* coverity[double_lock] */
658659
ucs_rcache_check_inv_queue(rcache, UCS_RCACHE_REGION_PUT_FLAG_ADD_TO_GC);
659660
/* coverity[double_unlock] */
660-
pthread_rwlock_unlock(&rcache->pgt_lock);
661+
ucs_rw_spinlock_write_unlock(&rcache->pgt_lock);
661662
return;
662663
}
663664

@@ -703,11 +704,11 @@ static void ucs_rcache_purge(ucs_rcache_t *rcache)
703704
/* Lock must be held in write mode */
704705
static void ucs_rcache_clean(ucs_rcache_t *rcache)
705706
{
706-
pthread_rwlock_wrlock(&rcache->pgt_lock);
707+
ucs_rw_spinlock_write_lock(&rcache->pgt_lock);
707708
/* coverity[double_lock]*/
708709
ucs_rcache_check_inv_queue(rcache, 0);
709710
ucs_rcache_check_gc_list(rcache, 1);
710-
pthread_rwlock_unlock(&rcache->pgt_lock);
711+
ucs_rw_spinlock_write_unlock(&rcache->pgt_lock);
711712
}
712713

713714
/* Lock must be held in write mode */
@@ -940,7 +941,7 @@ ucs_status_t ucs_rcache_create_region(ucs_rcache_t *rcache, void *address,
940941
ucs_trace_func("rcache=%s, address=%p, length=%zu", rcache->name, address,
941942
length);
942943

943-
pthread_rwlock_wrlock(&rcache->pgt_lock);
944+
ucs_rw_spinlock_write_lock(&rcache->pgt_lock);
944945

945946
retry:
946947
/* Align to page size */
@@ -1061,7 +1062,7 @@ ucs_status_t ucs_rcache_create_region(ucs_rcache_t *rcache, void *address,
10611062
*region_p = region;
10621063
out_unlock:
10631064
/* coverity[double_unlock]*/
1064-
pthread_rwlock_unlock(&rcache->pgt_lock);
1065+
ucs_rw_spinlock_write_unlock(&rcache->pgt_lock);
10651066
return status;
10661067
}
10671068

@@ -1082,7 +1083,7 @@ ucs_status_t ucs_rcache_get(ucs_rcache_t *rcache, void *address, size_t length,
10821083
ucs_trace_func("rcache=%s, address=%p, length=%zu", rcache->name, address,
10831084
length);
10841085

1085-
pthread_rwlock_rdlock(&rcache->pgt_lock);
1086+
ucs_rw_spinlock_read_lock(&rcache->pgt_lock);
10861087
UCS_STATS_UPDATE_COUNTER(rcache->stats, UCS_RCACHE_GETS, 1);
10871088
if (ucs_queue_is_empty(&rcache->inv_q)) {
10881089
pgt_region = UCS_PROFILE_CALL(ucs_pgtable_lookup, &rcache->pgtable,
@@ -1096,12 +1097,12 @@ ucs_status_t ucs_rcache_get(ucs_rcache_t *rcache, void *address, size_t length,
10961097
ucs_rcache_region_lru_get(rcache, region);
10971098
*region_p = region;
10981099
UCS_STATS_UPDATE_COUNTER(rcache->stats, UCS_RCACHE_HITS_FAST, 1);
1099-
pthread_rwlock_unlock(&rcache->pgt_lock);
1100+
ucs_rw_spinlock_read_unlock(&rcache->pgt_lock);
11001101
return UCS_OK;
11011102
}
11021103
}
11031104
}
1104-
pthread_rwlock_unlock(&rcache->pgt_lock);
1105+
ucs_rw_spinlock_read_unlock(&rcache->pgt_lock);
11051106

11061107
/* Fall back to slow version (with rw lock) in following cases:
11071108
* - invalidation list not empty
@@ -1132,7 +1133,7 @@ void ucs_rcache_region_invalidate(ucs_rcache_t *rcache,
11321133
comp = ucs_mpool_get(&rcache->mp);
11331134
ucs_spin_unlock(&rcache->lock);
11341135

1135-
pthread_rwlock_wrlock(&rcache->pgt_lock);
1136+
ucs_rw_spinlock_write_lock(&rcache->pgt_lock);
11361137
if (comp != NULL) {
11371138
comp->func = cb;
11381139
comp->arg = arg;
@@ -1145,7 +1146,7 @@ void ucs_rcache_region_invalidate(ucs_rcache_t *rcache,
11451146
/* coverity[double_lock] */
11461147
ucs_rcache_region_invalidate_internal(rcache, region, 0);
11471148
/* coverity[double_unlock] */
1148-
pthread_rwlock_unlock(&rcache->pgt_lock);
1149+
ucs_rw_spinlock_write_unlock(&rcache->pgt_lock);
11491150
UCS_STATS_UPDATE_COUNTER(rcache->stats, UCS_RCACHE_PUTS, 1);
11501151
}
11511152

@@ -1170,10 +1171,10 @@ static void ucs_rcache_before_fork(void)
11701171
* again on-demand.
11711172
* - Other use cases shouldn't be affected
11721173
*/
1173-
pthread_rwlock_wrlock(&rcache->pgt_lock);
1174+
ucs_rw_spinlock_write_lock(&rcache->pgt_lock);
11741175
/* coverity[double_lock] */
11751176
ucs_rcache_invalidate_range(rcache, 0, UCS_PGT_ADDR_MAX, 0);
1176-
pthread_rwlock_unlock(&rcache->pgt_lock);
1177+
ucs_rw_spinlock_write_unlock(&rcache->pgt_lock);
11771178
}
11781179
}
11791180
pthread_mutex_unlock(&ucs_rcache_global_context.lock);
@@ -1272,7 +1273,6 @@ static UCS_CLASS_INIT_FUNC(ucs_rcache_t, const ucs_rcache_params_t *params,
12721273
{
12731274
ucs_status_t status;
12741275
size_t mp_obj_size, mp_align;
1275-
int ret;
12761276
ucs_mpool_params_t mp_params;
12771277

12781278
if (params->region_struct_size < sizeof(ucs_rcache_region_t)) {
@@ -1294,16 +1294,10 @@ static UCS_CLASS_INIT_FUNC(ucs_rcache_t, const ucs_rcache_params_t *params,
12941294

12951295
self->params = *params;
12961296

1297-
ret = pthread_rwlock_init(&self->pgt_lock, NULL);
1298-
if (ret) {
1299-
ucs_error("pthread_rwlock_init() failed: %m");
1300-
status = UCS_ERR_INVALID_PARAM;
1301-
goto err_destroy_stats;
1302-
}
1303-
1297+
ucs_rw_spinlock_init(&self->pgt_lock);
13041298
status = ucs_spinlock_init(&self->lock, 0);
13051299
if (status != UCS_OK) {
1306-
goto err_destroy_rwlock;
1300+
goto err_destroy_stats;
13071301
}
13081302

13091303
status = ucs_pgtable_init(&self->pgtable, ucs_rcache_pgt_dir_alloc,
@@ -1376,8 +1370,6 @@ static UCS_CLASS_INIT_FUNC(ucs_rcache_t, const ucs_rcache_params_t *params,
13761370
ucs_pgtable_cleanup(&self->pgtable);
13771371
err_destroy_inv_q_lock:
13781372
ucs_spinlock_destroy(&self->lock);
1379-
err_destroy_rwlock:
1380-
pthread_rwlock_destroy(&self->pgt_lock);
13811373
err_destroy_stats:
13821374
UCS_STATS_NODE_FREE(self->stats);
13831375
err_free_name:
@@ -1408,7 +1400,6 @@ static UCS_CLASS_CLEANUP_FUNC(ucs_rcache_t)
14081400
ucs_mpool_cleanup(&self->mp, 1);
14091401
ucs_pgtable_cleanup(&self->pgtable);
14101402
ucs_spinlock_destroy(&self->lock);
1411-
pthread_rwlock_destroy(&self->pgt_lock);
14121403
UCS_STATS_NODE_FREE(self->stats);
14131404
ucs_free(self->name);
14141405
ucs_free(self->distribution);

src/ucs/memory/rcache_int.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <ucs/stats/stats.h>
1414
#include <ucs/sys/ptr_arith.h>
1515
#include <ucs/type/spinlock.h>
16+
#include <ucs/type/rwlock.h>
1617

1718

1819
#define ucs_rcache_region_log_lvl(_level, _message, ...) \
@@ -66,7 +67,7 @@ typedef struct ucs_rcache_distribution {
6667
struct ucs_rcache {
6768
ucs_rcache_params_t params; /**< rcache parameters (immutable) */
6869

69-
pthread_rwlock_t pgt_lock; /**< Protects the page table and all
70+
ucs_rw_spinlock_t pgt_lock; /**< Protects the page table and all
7071
regions whose refcount is 0 */
7172
ucs_pgtable_t pgtable; /**< page table to hold the regions */
7273

src/ucs/memory/rcache_vfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ static void ucs_rcache_vfs_show_primitive(void *obj, ucs_string_buffer_t *strb,
5454
{
5555
ucs_rcache_t *rcache = obj;
5656

57-
pthread_rwlock_rdlock(&rcache->pgt_lock);
57+
ucs_rw_spinlock_read_lock(&rcache->pgt_lock);
5858
ucs_vfs_show_primitive(obj, strb, arg_ptr, arg_u64);
59-
pthread_rwlock_unlock(&rcache->pgt_lock);
59+
ucs_rw_spinlock_read_unlock(&rcache->pgt_lock);
6060
}
6161

6262
static void ucs_rcache_vfs_init_regions_distribution(ucs_rcache_t *rcache)

test/gtest/ucs/test_rcache.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -972,9 +972,9 @@ UCS_TEST_F(test_rcache_stats, unmap_dereg_with_lock) {
972972
* We can have more unmap events if releasing the region structure triggers
973973
* releasing memory back to the OS.
974974
*/
975-
pthread_rwlock_wrlock(&m_rcache->pgt_lock);
975+
ucs_rw_spinlock_write_lock(&m_rcache->pgt_lock);
976976
munmap(mem, size1);
977-
pthread_rwlock_unlock(&m_rcache->pgt_lock);
977+
ucs_rw_spinlock_write_unlock(&m_rcache->pgt_lock);
978978

979979
EXPECT_GE(get_counter(UCS_RCACHE_UNMAPS), 1);
980980
EXPECT_EQ(0, get_counter(UCS_RCACHE_UNMAP_INVALIDATES));
@@ -1026,9 +1026,9 @@ UCS_TEST_F(test_rcache_stats, hits_slow) {
10261026
r1 = get(mem2, size1);
10271027

10281028
/* generate unmap event under lock, to roce using invalidation queue */
1029-
pthread_rwlock_rdlock(&m_rcache->pgt_lock);
1029+
ucs_rw_spinlock_read_lock(&m_rcache->pgt_lock);
10301030
munmap(mem1, size1);
1031-
pthread_rwlock_unlock(&m_rcache->pgt_lock);
1031+
ucs_rw_spinlock_read_unlock(&m_rcache->pgt_lock);
10321032

10331033
EXPECT_EQ(1, get_counter(UCS_RCACHE_UNMAPS));
10341034

0 commit comments

Comments
 (0)