Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f06d9686 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Matthew Wilcox
Browse files

Introduce down_killable()



down_killable() is the functional counterpart of mutex_lock_killable.

Signed-off-by: default avatarMatthew Wilcox <willy@linux.intel.com>
parent 64ac24e7
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -61,6 +61,12 @@ extern void down(struct semaphore *sem);
 */
extern int __must_check down_interruptible(struct semaphore *sem);

/*
 * As down_interruptible(), except the sleep may only be interrupted by
 * signals which are fatal to this process.
 */
extern int __must_check down_killable(struct semaphore *sem);

/*
 * As down(), except this function will not sleep.  It will return 0 if it
 * acquired the semaphore and 1 if the semaphore was contended.  This
+22 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@

static noinline void __down(struct semaphore *sem);
static noinline int __down_interruptible(struct semaphore *sem);
static noinline int __down_killable(struct semaphore *sem);
static noinline void __up(struct semaphore *sem);

void down(struct semaphore *sem)
@@ -61,6 +62,20 @@ int down_interruptible(struct semaphore *sem)
}
EXPORT_SYMBOL(down_interruptible);

int down_killable(struct semaphore *sem)
{
	unsigned long flags;
	int result = 0;

	spin_lock_irqsave(&sem->lock, flags);
	if (unlikely(sem->count-- <= 0))
		result = __down_killable(sem);
	spin_unlock_irqrestore(&sem->lock, flags);

	return result;
}
EXPORT_SYMBOL(down_killable);

/**
 * down_trylock - try to acquire the semaphore, without waiting
 * @sem: the semaphore to be acquired
@@ -143,6 +158,8 @@ static inline int __sched __down_common(struct semaphore *sem, long state)
	for (;;) {
		if (state == TASK_INTERRUPTIBLE && signal_pending(task))
			goto interrupted;
		if (state == TASK_KILLABLE && fatal_signal_pending(task))
			goto interrupted;
		__set_task_state(task, state);
		spin_unlock_irq(&sem->lock);
		schedule();
@@ -178,6 +195,11 @@ static noinline int __sched __down_interruptible(struct semaphore *sem)
	return __down_common(sem, TASK_INTERRUPTIBLE);
}

static noinline int __sched __down_killable(struct semaphore *sem)
{
	return __down_common(sem, TASK_KILLABLE);
}

static noinline void __sched __up(struct semaphore *sem)
{
	if (unlikely(list_empty(&sem->wait_list)))