Skip to content

Commit ab5fef6

Browse files
committed
locking: fix breakage on UEK4
It's nice to have it working on UEK4 even if we're not testing it much anymore. Signed-off-by: Stephen Brennan <[email protected]>
1 parent 731696c commit ab5fef6

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

drgn_tools/locking.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,17 @@ def for_each_rwsem_waiter_entity(rwsem: Object) -> Iterable[Object]:
338338
yield waiter
339339

340340

341+
def rwsem_count(rwsem: Object) -> int:
342+
try:
343+
return rwsem.count.counter.value_()
344+
except AttributeError:
345+
# For all modern kernels, rwsem.count is an atomic_long_t. Prior to
346+
# 8ee62b1870be8 ("locking/rwsem: Convert sem->count to
347+
# 'atomic_long_t'"), which was merged in 4.8, it was a long. It's not
348+
# too hard to fall back.
349+
return rwsem.count.value_()
350+
351+
341352
def get_rwsem_owner(rwsem: Object) -> Tuple[Object, "RwsemStateCode"]:
342353
"""
343354
Find owner of given rwsem
@@ -346,7 +357,7 @@ def get_rwsem_owner(rwsem: Object) -> Tuple[Object, "RwsemStateCode"]:
346357
:returns: type of owner and ``struct task_struct *`` if owner can be found, NULL otherwise
347358
"""
348359
prog = rwsem.prog_
349-
if not rwsem.count.counter.value_():
360+
if not rwsem_count(rwsem):
350361
return NULL(prog, "struct task_struct *"), RwsemStateCode.UNLOCKED
351362

352363
if is_rwsem_writer_owned(rwsem):
@@ -461,12 +472,13 @@ def is_rwsem_reader_owned(rwsem: Object) -> bool:
461472
case when type of owner could not be determined or when rwsem
462473
is free.)
463474
"""
464-
if not rwsem.count.counter.value_(): # rwsem is free
475+
count = rwsem_count(rwsem)
476+
if not count: # rwsem is free
465477
return False
466478
if rwsem.owner.type_.type_name() == "atomic_long_t":
467-
owner_is_writer = rwsem.count.counter.value_() & _RWSEM_WRITER_LOCKED
479+
owner_is_writer = count & _RWSEM_WRITER_LOCKED
468480
owner_is_reader = (
469-
(rwsem.count.counter.value_() & _RWSEM_READER_MASK)
481+
(count & _RWSEM_READER_MASK)
470482
and (rwsem.owner.counter.value_() & _RWSEM_READER_OWNED)
471483
and (owner_is_writer == 0)
472484
)
@@ -491,11 +503,12 @@ def is_rwsem_writer_owned(rwsem: Object) -> bool:
491503
case when type of owner could not be determined or when rwsem
492504
was free.)
493505
"""
494-
if not rwsem.count.counter.value_(): # rwsem is free
506+
count = rwsem_count(rwsem)
507+
if not count: # rwsem is free
495508
return False
496509

497510
if rwsem.owner.type_.type_name() == "atomic_long_t":
498-
owner_is_writer = rwsem.count.counter.value_() & _RWSEM_WRITER_LOCKED
511+
owner_is_writer = count & _RWSEM_WRITER_LOCKED
499512
return bool(owner_is_writer)
500513
else:
501514
if not rwsem.owner.value_():
@@ -536,7 +549,8 @@ def get_rwsem_info(rwsem: Object, callstack: int = 0) -> None:
536549
# of rwsem ->count and ->owner bits.
537550

538551
print(f"({rwsem.type_.type_name()})0x{rwsem.value_():x}")
539-
if not rwsem.count.counter.value_():
552+
count = rwsem_count(rwsem)
553+
if not count:
540554
print("rwsem is free.")
541555
return
542556

@@ -557,7 +571,7 @@ def get_rwsem_info(rwsem: Object, callstack: int = 0) -> None:
557571
# So try to retrieve that info.
558572
if rwsem.owner.type_.type_name() == "atomic_long_t":
559573
num_readers = (
560-
rwsem.count.counter.value_() & _RWSEM_READER_MASK
574+
count & _RWSEM_READER_MASK
561575
) >> _RWSEM_READER_SHIFT
562576
print(f"Owned by {num_readers} reader(s)")
563577
else:

0 commit comments

Comments
 (0)