Skip to content

Commit d4980ae

Browse files
author
Mukesh Chaurasiya
committed
powerpc/pseries/vas: Add VAS IRQ primary handler
Bugzilla: https://bugzilla.redhat.com/2130348 commit 89ed0b7 Author: Haren Myneni <haren@linux.ibm.com> Date: Sun Oct 9 20:41:25 2022 -0700 powerpc/pseries/vas: Add VAS IRQ primary handler irq_default_primary_handler() can be used only with IRQF_ONESHOT flag, but the flag disables IRQ before executing the thread handler and enables it after the interrupt is handled. But this IRQ disable sets the VAS IRQ OFF state in the hypervisor. In case if NX faults during this window, the hypervisor will not deliver the fault interrupt to the partition and the user space may wait continuously for the CSB update. So use VAS specific IRQ handler instead of calling the default primary handler. Increment pending_faults counter in IRQ handler and the bottom thread handler will process all faults based on this counter. In case if the another interrupt is received while the thread is running, it will be processed using this counter. The synchronization of top and bottom handlers will be done with IRQTF_RUNTHREAD flag and will re-enter to bottom half if this flag is set. Signed-off-by: Haren Myneni <haren@linux.ibm.com> Reviewed-by: Frederic Barrat <fbarrat@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/aaad8813b4762a6753cfcd0b605a7574a5192ec7.camel@linux.ibm.com Signed-off-by: Mukesh Chaurasiya <mchauras@redhat.com>
1 parent 99bfdd4 commit d4980ae

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

arch/powerpc/platforms/pseries/vas.c

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,16 +192,41 @@ irqreturn_t pseries_vas_fault_thread_fn(int irq, void *data)
192192
struct vas_user_win_ref *tsk_ref;
193193
int rc;
194194

195-
rc = h_get_nx_fault(txwin->vas_win.winid, (u64)virt_to_phys(&crb));
196-
if (!rc) {
197-
tsk_ref = &txwin->vas_win.task_ref;
198-
vas_dump_crb(&crb);
199-
vas_update_csb(&crb, tsk_ref);
195+
while (atomic_read(&txwin->pending_faults)) {
196+
rc = h_get_nx_fault(txwin->vas_win.winid, (u64)virt_to_phys(&crb));
197+
if (!rc) {
198+
tsk_ref = &txwin->vas_win.task_ref;
199+
vas_dump_crb(&crb);
200+
vas_update_csb(&crb, tsk_ref);
201+
}
202+
atomic_dec(&txwin->pending_faults);
200203
}
201204

202205
return IRQ_HANDLED;
203206
}
204207

208+
/*
209+
* irq_default_primary_handler() can be used only with IRQF_ONESHOT
210+
* which disables IRQ before executing the thread handler and enables
211+
* it after. But this disabling interrupt sets the VAS IRQ OFF
212+
* state in the hypervisor. If the NX generates fault interrupt
213+
* during this window, the hypervisor will not deliver this
214+
* interrupt to the LPAR. So use VAS specific IRQ handler instead
215+
* of calling the default primary handler.
216+
*/
217+
static irqreturn_t pseries_vas_irq_handler(int irq, void *data)
218+
{
219+
struct pseries_vas_window *txwin = data;
220+
221+
/*
222+
* The thread hanlder will process this interrupt if it is
223+
* already running.
224+
*/
225+
atomic_inc(&txwin->pending_faults);
226+
227+
return IRQ_WAKE_THREAD;
228+
}
229+
205230
/*
206231
* Allocate window and setup IRQ mapping.
207232
*/
@@ -232,8 +257,9 @@ static int allocate_setup_window(struct pseries_vas_window *txwin,
232257
goto out_irq;
233258
}
234259

235-
rc = request_threaded_irq(txwin->fault_virq, NULL,
236-
pseries_vas_fault_thread_fn, IRQF_ONESHOT,
260+
rc = request_threaded_irq(txwin->fault_virq,
261+
pseries_vas_irq_handler,
262+
pseries_vas_fault_thread_fn, 0,
237263
txwin->name, txwin);
238264
if (rc) {
239265
pr_err("VAS-Window[%d]: Request IRQ(%u) failed with %d\n",

arch/powerpc/platforms/pseries/vas.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ struct pseries_vas_window {
132132
u64 flags;
133133
char *name;
134134
int fault_virq;
135+
atomic_t pending_faults; /* Number of pending faults */
135136
};
136137

137138
int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps);

0 commit comments

Comments
 (0)