Module Name: src Committed By: skrll Date: Tue Dec 21 07:11:02 UTC 2021
Modified Files: src/sys/arch/arm/pic: pic.c Log Message: Fix a bug where pic_establish_intr would fail to call pic_establish_irq if a free pic__iplsources slot was found, i.e. an interrupt handler at the same ipl had been disestablished previously. To generate a diff of this commit: cvs rdiff -u -r1.77 -r1.78 src/sys/arch/arm/pic/pic.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/arch/arm/pic/pic.c diff -u src/sys/arch/arm/pic/pic.c:1.77 src/sys/arch/arm/pic/pic.c:1.78 --- src/sys/arch/arm/pic/pic.c:1.77 Tue Dec 21 07:07:32 2021 +++ src/sys/arch/arm/pic/pic.c Tue Dec 21 07:11:02 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: pic.c,v 1.77 2021/12/21 07:07:32 skrll Exp $ */ +/* $NetBSD: pic.c,v 1.78 2021/12/21 07:11:02 skrll Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ #include "opt_multiprocessor.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.77 2021/12/21 07:07:32 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.78 2021/12/21 07:11:02 skrll Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -754,42 +754,44 @@ pic_establish_intr(struct pic_softc *pic /* * First try to use an existing slot which is empty. */ + bool found = false; for (off = pic_ipl_offset[ipl]; off < pic_ipl_offset[ipl + 1]; off++) { if (pic__iplsources[off] == NULL) { - is->is_iplidx = off - pic_ipl_offset[ipl]; - pic__iplsources[off] = is; - goto unblock; + found = true; + break; } } - /* - * Move up all the sources by one. - */ - if (ipl < NIPL) { - off = pic_ipl_offset[ipl + 1]; - memmove(&pic__iplsources[off + 1], &pic__iplsources[off], - sizeof(pic__iplsources[0]) * (pic_ipl_offset[NIPL] - off)); - } + if (!found) { + /* + * Move up all the sources by one. + */ + if (ipl < NIPL) { + off = pic_ipl_offset[ipl + 1]; + memmove(&pic__iplsources[off + 1], &pic__iplsources[off], + sizeof(pic__iplsources[0]) * (pic_ipl_offset[NIPL] - off)); + } - /* - * Advance the offset of all IPLs higher than this. Include an - * extra one as well. Thus the number of sources per ipl is - * pic_ipl_offset[ipl + 1] - pic_ipl_offset[ipl]. - */ - for (nipl = ipl + 1; nipl <= NIPL; nipl++) - pic_ipl_offset[nipl]++; + /* + * Advance the offset of all IPLs higher than this. Include an + * extra one as well. Thus the number of sources per ipl is + * pic_ipl_offset[ipl + 1] - pic_ipl_offset[ipl]. + */ + for (nipl = ipl + 1; nipl <= NIPL; nipl++) + pic_ipl_offset[nipl]++; + + off = pic_ipl_offset[ipl + 1] - 1; + } /* - * Insert into the previously made position at the end of this IPL's - * sources. + * Insert into the 'found' or the just made slot position at the end + * of this IPL's sources. */ - off = pic_ipl_offset[ipl + 1] - 1; is->is_iplidx = off - pic_ipl_offset[ipl]; pic__iplsources[off] = is; (*pic->pic_ops->pic_establish_irq)(pic, is); -unblock: if (!mp_online || !is->is_mpsafe || !is->is_percpu) { (*pic->pic_ops->pic_unblock_irqs)(pic, is->is_irq & ~0x1f, __BIT(is->is_irq & 0x1f));