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

Commit f2db2e6c authored by Heiko Carstens's avatar Heiko Carstens Committed by Martin Schwidefsky
Browse files

[S390] pfault: cpu hotplug vs missing completion interrupts



On cpu hot remove a PFAULT CANCEL command is sent to the hypervisor
which in turn will cancel all outstanding pfault requests that have
been issued on that cpu (the same happens with a SIGP cpu reset).

The result is that we end up with uninterruptible processes where
the interrupt that would wake up these processes never arrives.

In order to solve this all processes which wait for a pfault
completion interrupt get woken up after a cpu hot remove. The worst
case that could happen is that they fault again and in turn need to
wait again.

Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent b456d94a
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -124,7 +124,7 @@ struct _lowcore {
	/* Address space pointer. */
	/* Address space pointer. */
	__u32	kernel_asce;			/* 0x02ac */
	__u32	kernel_asce;			/* 0x02ac */
	__u32	user_asce;			/* 0x02b0 */
	__u32	user_asce;			/* 0x02b0 */
	__u8	pad_0x02b4[0x02b8-0x02b4];	/* 0x02b4 */
	__u32	current_pid;			/* 0x02b4 */


	/* SMP info area */
	/* SMP info area */
	__u32	cpu_nr;				/* 0x02b8 */
	__u32	cpu_nr;				/* 0x02b8 */
@@ -255,7 +255,7 @@ struct _lowcore {
	/* Address space pointer. */
	/* Address space pointer. */
	__u64	kernel_asce;			/* 0x0310 */
	__u64	kernel_asce;			/* 0x0310 */
	__u64	user_asce;			/* 0x0318 */
	__u64	user_asce;			/* 0x0318 */
	__u8	pad_0x0320[0x0328-0x0320];	/* 0x0320 */
	__u64	current_pid;			/* 0x0320 */


	/* SMP info area */
	/* SMP info area */
	__u32	cpu_nr;				/* 0x0328 */
	__u32	cpu_nr;				/* 0x0328 */
+1 −0
Original line number Original line Diff line number Diff line
@@ -84,6 +84,7 @@ struct thread_struct {
	struct per_event per_event;	/* Cause of the last PER trap */
	struct per_event per_event;	/* Cause of the last PER trap */
        /* pfault_wait is used to block the process on a pfault event */
        /* pfault_wait is used to block the process on a pfault event */
	unsigned long pfault_wait;
	unsigned long pfault_wait;
	struct list_head list;
};
};


typedef struct thread_struct thread_struct;
typedef struct thread_struct thread_struct;
+1 −0
Original line number Original line Diff line number Diff line
@@ -124,6 +124,7 @@ int main(void)
	DEFINE(__LC_LAST_UPDATE_TIMER, offsetof(struct _lowcore, last_update_timer));
	DEFINE(__LC_LAST_UPDATE_TIMER, offsetof(struct _lowcore, last_update_timer));
	DEFINE(__LC_LAST_UPDATE_CLOCK, offsetof(struct _lowcore, last_update_clock));
	DEFINE(__LC_LAST_UPDATE_CLOCK, offsetof(struct _lowcore, last_update_clock));
	DEFINE(__LC_CURRENT, offsetof(struct _lowcore, current_task));
	DEFINE(__LC_CURRENT, offsetof(struct _lowcore, current_task));
	DEFINE(__LC_CURRENT_PID, offsetof(struct _lowcore, current_pid));
	DEFINE(__LC_THREAD_INFO, offsetof(struct _lowcore, thread_info));
	DEFINE(__LC_THREAD_INFO, offsetof(struct _lowcore, thread_info));
	DEFINE(__LC_KERNEL_STACK, offsetof(struct _lowcore, kernel_stack));
	DEFINE(__LC_KERNEL_STACK, offsetof(struct _lowcore, kernel_stack));
	DEFINE(__LC_ASYNC_STACK, offsetof(struct _lowcore, async_stack));
	DEFINE(__LC_ASYNC_STACK, offsetof(struct _lowcore, async_stack));
+1 −0
Original line number Original line Diff line number Diff line
@@ -212,6 +212,7 @@ __switch_to:
	lctl	%c4,%c4,__TASK_pid(%r3)		# load pid to control reg. 4
	lctl	%c4,%c4,__TASK_pid(%r3)		# load pid to control reg. 4
	lm	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
	lm	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
	st	%r3,__LC_CURRENT		# store task struct of next
	st	%r3,__LC_CURRENT		# store task struct of next
	mvc	__LC_CURRENT_PID(4,%r0),__TASK_pid(%r3)	# store pid of next
	st	%r5,__LC_THREAD_INFO		# store thread info of next
	st	%r5,__LC_THREAD_INFO		# store thread info of next
	ahi	%r5,STACK_SIZE			# end of kernel stack of next
	ahi	%r5,STACK_SIZE			# end of kernel stack of next
	st	%r5,__LC_KERNEL_STACK		# store end of kernel stack
	st	%r5,__LC_KERNEL_STACK		# store end of kernel stack
+1 −0
Original line number Original line Diff line number Diff line
@@ -220,6 +220,7 @@ __switch_to:
	lctl	%c4,%c4,__TASK_pid(%r3)		# load pid to control reg. 4
	lctl	%c4,%c4,__TASK_pid(%r3)		# load pid to control reg. 4
	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
	stg	%r3,__LC_CURRENT		# store task struct of next
	stg	%r3,__LC_CURRENT		# store task struct of next
	mvc	__LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next
	stg	%r5,__LC_THREAD_INFO		# store thread info of next
	stg	%r5,__LC_THREAD_INFO		# store thread info of next
	aghi	%r5,STACK_SIZE			# end of kernel stack of next
	aghi	%r5,STACK_SIZE			# end of kernel stack of next
	stg	%r5,__LC_KERNEL_STACK		# store end of kernel stack
	stg	%r5,__LC_KERNEL_STACK		# store end of kernel stack
Loading