Module Name: src Committed By: riastradh Date: Mon Jan 29 01:05:55 UTC 2024
Modified Files: src/sys/dev/pci: agp_i810.c Log Message: agp_i810(4): Use ipi(9) for chipset flush on all CPUs, not xcall(9). i915 now calls into this with a spin lock held, so we have to use ipi(9), which spin-waits for the other CPUs to complete, rather than xcall(9), which may sleep-wait. Fortunately, this is just to execute WBINVD on x86 (and if this code ever runs on other architectures, which it probably doesn't, it'll be a similar barrier instruction), so spinning to wait for that on all CPUs isn't too costly. PR kern/57878 XXX pullup-10 To generate a diff of this commit: cvs rdiff -u -r1.125 -r1.126 src/sys/dev/pci/agp_i810.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/agp_i810.c diff -u src/sys/dev/pci/agp_i810.c:1.125 src/sys/dev/pci/agp_i810.c:1.126 --- src/sys/dev/pci/agp_i810.c:1.125 Sun Jul 17 10:10:45 2022 +++ src/sys/dev/pci/agp_i810.c Mon Jan 29 01:05:55 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: agp_i810.c,v 1.125 2022/07/17 10:10:45 riastradh Exp $ */ +/* $NetBSD: agp_i810.c,v 1.126 2024/01/29 01:05:55 riastradh Exp $ */ /*- * Copyright (c) 2000 Doug Rabson @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.125 2022/07/17 10:10:45 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.126 2024/01/29 01:05:55 riastradh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -180,7 +180,7 @@ agp_i810_post_gtt_entry(struct agp_i810_ } static void -agp_flush_cache_xc(void *a __unused, void *b __unused) +agp_flush_cache_ipi(void *cookie __unused) { agp_flush_cache(); @@ -204,11 +204,19 @@ agp_i810_chipset_flush(struct agp_i810_s * XXX Come to think of it, do these chipsets appear in * any multi-CPU systems? */ - if (cold) + if (cold) { agp_flush_cache(); - else - xc_wait(xc_broadcast(0, &agp_flush_cache_xc, - NULL, NULL)); + } else { + /* + * Caller may hold a spin lock, so use ipi(9) + * rather than xcall(9) here. + */ + ipi_msg_t msg = { .func = agp_flush_cache_ipi }; + kpreempt_disable(); + ipi_broadcast(&msg, /*skip_self*/false); + ipi_wait(&msg); + kpreempt_enable(); + } WRITE4(AGP_I830_HIC, READ4(AGP_I830_HIC) | __BIT(31)); while (ISSET(READ4(AGP_I830_HIC), __BIT(31))) { if (timo-- == 0)