// SPDX-License-Identifier: GPL-2.0-or-later#include<linux/slab.h>#include<linux/sched/rt.h>#include<linux/sched/task.h>#include"futex.h"#include"../locking/rtmutex_common.h"/* * PI code: */intrefill_pi_state_cache(void){structfutex_pi_state*pi_state;if(likely(current->futex.pi_state_cache))return0;pi_state=kzalloc_obj(*pi_state);if(!pi_state)return-ENOMEM;INIT_LIST_HEAD(&pi_state->list);/* pi_mutex gets initialized later */pi_state->owner=NULL;refcount_set(&pi_state->refcount,1);pi_state->key=FUTEX_KEY_INIT;current->futex.pi_state_cache=pi_state;return0;}staticstructfutex_pi_state*alloc_pi_state(void){structfutex_pi_state*pi_state=current->futex.pi_state_cache;WARN_ON(!pi_state);current->futex.pi_state_cache=NULL;returnpi_state;}staticvoidpi_state_update_owner(structfutex_pi_state*pi_state,structtask_struct*new_owner){structtask_struct*old_owner=pi_state->owner;lockdep_assert_held(&pi_state->pi_mutex.wait_lock);if(old_owner){raw_spin_lock(&old_owner->pi_lock);WARN_ON(list_empty(&pi_state->list));list_del_init(&pi_state->list);raw_spin_unlock(&old_owner->pi_lock);}if(new_owner){raw_spin_lock(&new_owner->pi_lock);WARN_ON(!list_empty(&pi_state->list));list_add(&pi_state->list,&new_owner->futex.pi_state_list);pi_state->owner=new_owner;raw_spin_unlock(&new_owner->pi_lock);}}voidget_pi_state(structfutex_pi_state*pi_state){WARN_ON_ONCE(!refcount_inc_not_zero(&pi_state->refcount));}/* * Drops a reference to the pi_state object and frees or caches it * when the last reference is gone. */voidput_pi_state(structfutex_pi_state*pi_state){if(!pi_state)return;