Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/xive: prepare all hcalls to support long busy delays

This is not the case for the moment, but future releases of pHyp might
need to introduce some synchronisation routines under the hood which
would make the XIVE hcalls longer to complete.

As this was done for H_INT_RESET, let's wrap the other hcalls in a
loop catching the H_LONG_BUSY_* codes.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

Cédric Le Goater and committed by
Michael Ellerman
282498d6 72224846

+28 -8
+28 -8
arch/powerpc/sysdev/xive/spapr.c
··· 164 164 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 165 165 long rc; 166 166 167 - rc = plpar_hcall(H_INT_GET_SOURCE_INFO, retbuf, flags, lisn); 167 + do { 168 + rc = plpar_hcall(H_INT_GET_SOURCE_INFO, retbuf, flags, lisn); 169 + } while (plpar_busy_delay(rc)); 170 + 168 171 if (rc) { 169 172 pr_err("H_INT_GET_SOURCE_INFO lisn=%ld failed %ld\n", lisn, rc); 170 173 return rc; ··· 200 197 flags, lisn, target, prio, sw_irq); 201 198 202 199 203 - rc = plpar_hcall_norets(H_INT_SET_SOURCE_CONFIG, flags, lisn, 204 - target, prio, sw_irq); 200 + do { 201 + rc = plpar_hcall_norets(H_INT_SET_SOURCE_CONFIG, flags, lisn, 202 + target, prio, sw_irq); 203 + } while (plpar_busy_delay(rc)); 204 + 205 205 if (rc) { 206 206 pr_err("H_INT_SET_SOURCE_CONFIG lisn=%ld target=%lx prio=%lx failed %ld\n", 207 207 lisn, target, prio, rc); ··· 223 217 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 224 218 long rc; 225 219 226 - rc = plpar_hcall(H_INT_GET_QUEUE_INFO, retbuf, flags, target, priority); 220 + do { 221 + rc = plpar_hcall(H_INT_GET_QUEUE_INFO, retbuf, flags, target, 222 + priority); 223 + } while (plpar_busy_delay(rc)); 224 + 227 225 if (rc) { 228 226 pr_err("H_INT_GET_QUEUE_INFO cpu=%ld prio=%ld failed %ld\n", 229 227 target, priority, rc); ··· 256 246 pr_devel("H_INT_SET_QUEUE_CONFIG flags=%lx target=%lx priority=%lx qpage=%lx qsize=%lx\n", 257 247 flags, target, priority, qpage, qsize); 258 248 259 - rc = plpar_hcall_norets(H_INT_SET_QUEUE_CONFIG, flags, target, 260 - priority, qpage, qsize); 249 + do { 250 + rc = plpar_hcall_norets(H_INT_SET_QUEUE_CONFIG, flags, target, 251 + priority, qpage, qsize); 252 + } while (plpar_busy_delay(rc)); 253 + 261 254 if (rc) { 262 255 pr_err("H_INT_SET_QUEUE_CONFIG cpu=%ld prio=%ld qpage=%lx returned %ld\n", 263 256 target, priority, qpage, rc); ··· 274 261 { 275 262 long rc; 276 263 277 - rc = plpar_hcall_norets(H_INT_SYNC, flags, lisn); 264 + do { 265 + rc = plpar_hcall_norets(H_INT_SYNC, flags, lisn); 266 + } while (plpar_busy_delay(rc)); 267 + 278 268 if (rc) { 279 269 pr_err("H_INT_SYNC lisn=%ld returned %ld\n", lisn, rc); 280 270 return rc; ··· 300 284 pr_devel("H_INT_ESB flags=%lx lisn=%lx offset=%lx in=%lx\n", 301 285 flags, lisn, offset, in_data); 302 286 303 - rc = plpar_hcall(H_INT_ESB, retbuf, flags, lisn, offset, in_data); 287 + do { 288 + rc = plpar_hcall(H_INT_ESB, retbuf, flags, lisn, offset, 289 + in_data); 290 + } while (plpar_busy_delay(rc)); 291 + 304 292 if (rc) { 305 293 pr_err("H_INT_ESB lisn=%ld offset=%ld returned %ld\n", 306 294 lisn, offset, rc);