Re: pf: remove 'one shot rules'
Hello, mikeb@ and me were poking about same idea some time ago (?2016?). But the idea never turned to diff. If I remember correct the only meaningful use case we could come up with for once rules is [t]ftp-proxy. But neither one seems to use once rules at all. I'm OK with removing 'once' rules. From my point of view it adds too much complexity for little win. I've found just one nit in your diff so far, see below. thanks and regards sashan > Index: sys/net/pfvar.h > === > RCS file: /cvs/src/sys/net/pfvar.h,v > retrieving revision 1.493 > diff -u -p -u -p -r1.493 pfvar.h > --- sys/net/pfvar.h 17 Nov 2019 08:25:05 - 1.493 > +++ sys/net/pfvar.h 24 Jan 2020 06:12:19 - > @@ -596,10 +596,6 @@ struct pf_rule { > u_int16_t port; > u_int8_ttype; > } divert; > - > - SLIST_ENTRY(pf_rule) gcle; > - struct pf_ruleset *ruleset; > - time_t exptime; > }; > > /* rule flags */ > @@ -617,7 +613,6 @@ struct pf_rule { > #define PFRULE_IFBOUND 0x0001 /* if-bound */ > #define PFRULE_STATESLOPPY 0x0002 /* sloppy state tracking */ > #define PFRULE_PFLOW 0x0004 > -#define PFRULE_ONCE 0x0010 /* one shot rule */ > #define PFRULE_AFTO 0x0020 /* af-to rule */ > #define PFRULE_EXPIRED 0x0040 /* one shot rule hit by > pkt */ PFRULE_EXPIRED, can be also removed.
Add support for notifications about audio(4) "mixer" controls changes
The diff bellow allows programs to get notifications about changes of audio controls. Programs open the /dev/audioctlN device node and use the read(4) syscall to get the index of each changed control. There may be only one reader at a time. Supporting multiple readers would be much more complicated and the purpose of this diff is to allow sndiod(8) to expose the controls to programs. So, there will be one reader only. To test the diff, run: hexdump -ve '1/4 "%d\n"' 0 struct wskbd_vol spkr, mic; struct task wskbd_task; @@ -1192,6 +1205,8 @@ audio_attach(struct device *parent, stru sc->mix_nent = mi->index; sc->mix_ents = mallocarray(sc->mix_nent, sizeof(struct mixer_ctrl), M_DEVBUF, M_WAITOK); + sc->mix_evbuf = mallocarray(sc->mix_nent, + sizeof(struct mixer_ev), M_DEVBUF, M_WAITOK | M_ZERO); ent = sc->mix_ents; mi->index = 0; @@ -1329,6 +1344,7 @@ audio_detach(struct device *self, int fl } /* free resources */ + free(sc->mix_evbuf, M_DEVBUF, sc->mix_nent * sizeof(struct mixer_ev)); free(sc->mix_ents, M_DEVBUF, sc->mix_nent * sizeof(struct mixer_ctrl)); audio_buf_done(sc, >play); audio_buf_done(sc, >rec); @@ -1718,6 +1734,28 @@ audio_ioctl(struct audio_softc *sc, unsi return error; } +void +audio_event(struct audio_softc *sc, int addr) +{ + struct mixer_ev *e; + + mtx_enter(_lock); + if (sc->mix_isopen) { + e = sc->mix_evbuf + addr; + if (!e->pending) { + e->pending = 1; + e->next = sc->mix_pending; + sc->mix_pending = e; + } + if (sc->mix_blocking) { + wakeup(>mix_blocking); + sc->mix_blocking = 0; + } + selwakeup(>mix_sel); + } + mtx_leave(_lock); +} + int audio_mixer_devinfo(struct audio_softc *sc, struct mixer_devinfo *devinfo) { @@ -1784,6 +1822,7 @@ audio_mixer_set(struct audio_softc *sc, return error; if (sc->ops->commit_settings) return sc->ops->commit_settings(sc->arg); + audio_event(sc, c->dev); return 0; } @@ -1834,6 +1873,107 @@ audio_ioctl_mixer(struct audio_softc *sc } int +audio_mixer_read(struct audio_softc *sc, struct uio *uio, int ioflag) +{ + struct mixer_ev *e; + int data; + int error; + + DPRINTF("%s: mixer read: resid = %zd\n", DEVNAME(sc), uio->uio_resid); + + /* block if quiesced */ + while (sc->quiesce) + tsleep_nsec(>quiesce, 0, "mix_qrd", INFSLP); + + mtx_enter(_lock); + + /* if there are no events then sleep */ + while (!sc->mix_pending) { + if (ioflag & IO_NDELAY) { + mtx_leave(_lock); + return EWOULDBLOCK; + } + DPRINTF("%s: mixer read sleep\n", DEVNAME(sc)); + sc->mix_blocking = 1; + error = msleep_nsec(>mix_blocking, + _lock, PWAIT | PCATCH, "mix_rd", INFSLP); + if (!(sc->dev.dv_flags & DVF_ACTIVE)) + error = EIO; + if (error) { + DPRINTF("%s: mixer read woke up error = %d\n", + DEVNAME(sc), error); + mtx_leave(_lock); + return error; + } + } + + /* at this stage, there is an event to transfer */ + while (uio->uio_resid >= sizeof(int) && sc->mix_pending) { + e = sc->mix_pending; + sc->mix_pending = e->next; + e->pending = 0; + data = e - sc->mix_evbuf; + mtx_leave(_lock); + DPRINTF("%s: mixer read: %u\n", DEVNAME(sc), data); + error = uiomove(, sizeof(int), uio); + if (error) + return error; + mtx_enter(_lock); + } + + mtx_leave(_lock); + return 0; +} + +int +audio_mixer_poll(struct audio_softc *sc, int events, struct proc *p) +{ + int revents = 0; + + mtx_enter(_lock); + if (sc->mix_isopen && sc->mix_pending) + revents |= events & (POLLIN | POLLRDNORM); + if (revents == 0) { + if (events & (POLLIN | POLLRDNORM)) + selrecord(p, >mix_sel); + } + mtx_leave(_lock); + return revents; +} + +int +audio_mixer_open(struct audio_softc *sc, int flags) +{ + DPRINTF("%s: flags = 0x%x\n", __func__, flags); + + if (flags & FREAD) { + if (sc->mix_isopen) + return EBUSY; + sc->mix_isopen = 1; + } + return 0; +} + +int +audio_mixer_close(struct audio_softc *sc, int flags) +{ + int i; + + DPRINTF("%s: flags
hidmt(4): only allow hid_input kind
Hi, on the Pinebook Pro the trackpad isn't working. The reason is that the Y-coordinate is extracted twice. The first location has thevalue correctly, the second location has it zeroed or garbage. This is because when we iterate over the report, the Y-coordinate usage appears twice. This shouldn't happen, so why does it? Here's an excerpt of the report descriptor: Item(Global): Logical Maximum, data= [ 0x92 0x03 ] 914 Item(Global): Physical Maximum, data= [ 0x40 0x01 ] 320 Item(Local ): Usage, data= [ 0x31 ] 49 Direction-Y Item(Main ): Input, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Main ): Collection, data= [ 0x02 ] 2 Logical Directly after the Y-coordinate a collection ends and another starts. The end of the collection will make hid_get_item() return with an item where h.kind is hid_endcollection and h.usage is zero. The start of the new collection will make hid_get_item() return, and it will return with h.kind set to hid_collection and h.usage set to the last usage, which in this case is "Direction-Y". Since we don't filter out hid_(end)collection, we add this item to the list. So, by making sure we only add hid_input items, the Pinebook Pro's trackpad works. Now I'm not sure if the hid code is supposed to re-use the Y-coordi- nates usage on the next collection. If someone knows how that should work, please let me down. ok? Patrick diff --git a/sys/dev/hid/hidmt.c b/sys/dev/hid/hidmt.c index ee8dcadcc31..67eea46f0c0 100644 --- a/sys/dev/hid/hidmt.c +++ b/sys/dev/hid/hidmt.c @@ -176,6 +176,8 @@ hidmt_setup(struct device *self, struct hidmt *mt, void *desc, int dlen) if (h.report_ID != mt->sc_rep_input) continue; + if (h.kind != hid_input) + continue; switch (h.usage) { /* contact level usages */
Re: Add #define for RFC8622 IPTOS_DSCP_LE codepoint
On Sat, Jan 25, 2020 at 11:36:53PM +1100, Damien Miller wrote: > This adds a #define for the "lower effort" DSCP code point specified > by https://tools.ietf.org/html/rfc8622 > > People have asked to be able to use this OpenSSH for "don't care" > traffic. > > ok? OK job@
vlan: use SMR_SLIST instead of SRP to protect instance lists
Converting vlan(4) to use SMR instead of SRP to protect the instance lists is pretty simple. vlan_input() doesn't keep a reference to vlan_softcs outside the read critical section, so we don't need to reference count them any more. After the smr_barrier() in vlan_clone_destroy, all pointers to the vlan that were obtained from the instance lists have been dropped, so it's safe to free it. ok? Index: if_vlan.c === RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.202 diff -u -p -r1.202 if_vlan.c --- if_vlan.c 7 Nov 2019 07:36:32 - 1.202 +++ if_vlan.c 25 Jan 2020 22:38:17 - @@ -57,7 +57,7 @@ #include #include #include -#include +#include #include #include @@ -94,14 +94,15 @@ struct vlan_softc { uint16_t sc_type; /* non-standard ethertype or 0x8100 */ LIST_HEAD(__vlan_mchead, vlan_mc_entry) sc_mc_listhead; - SRPL_ENTRY(vlan_softc) sc_list; + SMR_SLIST_ENTRY(vlan_softc) sc_list; int sc_flags; - struct refcntsc_refcnt; struct task sc_ltask; struct task sc_dtask; struct ifih *sc_ifih; }; +SMR_SLIST_HEAD(vlan_list, vlan_softc); + #defineIFVF_PROMISC0x01/* the parent should be made promisc */ #defineIFVF_LLADDR 0x02/* don't inherit the parents mac */ @@ -109,7 +110,7 @@ struct vlan_softc { #define TAG_HASH_SIZE (1 << TAG_HASH_BITS) #define TAG_HASH_MASK (TAG_HASH_SIZE - 1) #define TAG_HASH(tag) (tag & TAG_HASH_MASK) -SRPL_HEAD(, vlan_softc) *vlan_tagh, *svlan_tagh; +struct vlan_list *vlan_tagh, *svlan_tagh; struct rwlock vlan_tagh_lk = RWLOCK_INITIALIZER("vlantag"); void vlanattach(int count); @@ -152,11 +153,6 @@ struct if_clone vlan_cloner = struct if_clone svlan_cloner = IF_CLONE_INITIALIZER("svlan", vlan_clone_create, vlan_clone_destroy); -void vlan_ref(void *, void *); -void vlan_unref(void *, void *); - -struct srpl_rc vlan_tagh_rc = SRPL_RC_INITIALIZER(vlan_ref, vlan_unref, NULL); - void vlanattach(int count) { @@ -175,8 +171,8 @@ vlanattach(int count) panic("vlanattach: hashinit"); for (i = 0; i < TAG_HASH_SIZE; i++) { - SRPL_INIT(_tagh[i]); - SRPL_INIT(_tagh[i]); + SMR_SLIST_INIT(_tagh[i]); + SMR_SLIST_INIT(_tagh[i]); } if_clone_attach(_cloner); @@ -207,7 +203,6 @@ vlan_clone_create(struct if_clone *ifc, else sc->sc_type = ETHERTYPE_VLAN; - refcnt_init(>sc_refcnt); sc->sc_txprio = IF_HDRPRIO_PACKET; sc->sc_rxprio = IF_HDRPRIO_OUTER; @@ -227,22 +222,6 @@ vlan_clone_create(struct if_clone *ifc, return (0); } -void -vlan_ref(void *null, void *v) -{ - struct vlan_softc *sc = v; - - refcnt_take(>sc_refcnt); -} - -void -vlan_unref(void *null, void *v) -{ - struct vlan_softc *sc = v; - - refcnt_rele_wake(>sc_refcnt); -} - int vlan_clone_destroy(struct ifnet *ifp) { @@ -257,7 +236,7 @@ vlan_clone_destroy(struct ifnet *ifp) ether_ifdetach(ifp); if_detach(ifp); - refcnt_finalize(>sc_refcnt, "vlanrefs"); + smr_barrier(); vlan_multi_free(sc); free(sc, M_DEVBUF, sizeof(*sc)); @@ -384,8 +363,7 @@ vlan_input(struct ifnet *ifp0, struct mb struct vlan_softc *sc; struct ether_vlan_header *evl; struct ether_header *eh; - SRPL_HEAD(, vlan_softc) *tagh, *list; - struct srp_ref sr; + struct vlan_list *tagh, *list; uint16_t tag; uint16_t etype; int rxprio; @@ -415,7 +393,8 @@ vlan_input(struct ifnet *ifp0, struct mb tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag); list = [TAG_HASH(tag)]; - SRPL_FOREACH(sc, , list, sc_list) { + smr_read_enter(); + SMR_SLIST_FOREACH(sc, list, sc_list) { if (ifp0->if_index == sc->sc_ifidx0 && tag == sc->sc_tag && etype == sc->sc_type) break; @@ -456,14 +435,14 @@ vlan_input(struct ifnet *ifp0, struct mb if_vinput(>sc_if, m); leave: - SRPL_LEAVE(); + smr_read_leave(); return (1); } int vlan_up(struct vlan_softc *sc) { - SRPL_HEAD(, vlan_softc) *tagh, *list; + struct vlan_list *tagh, *list; struct ifnet *ifp = >sc_if; struct ifnet *ifp0; int error = 0; @@ -531,7 +510,7 @@ vlan_up(struct vlan_softc *sc) if (error != 0) goto leave; - SRPL_INSERT_HEAD_LOCKED(_tagh_rc, list, sc, sc_list); + SMR_SLIST_INSERT_HEAD_LOCKED(list, sc, sc_list); rw_exit(_tagh_lk); /* Register callback for physical link state changes */ @@ -571,7 +550,7 @@ put: int vlan_down(struct vlan_softc *sc) { - SRPL_HEAD(, vlan_softc)
Re: apmd: fix autoaction timeout
Jeremie Courreges-Anglas wrote: > > The diff below improves the way apmd -z/-Z may trigger. > > I think the current behavior is bogus, incrementing and checking > apmtimeout like this doesn't make much sense. this all seems reasonable to me. > - I think we want some throttling mechanism, like wait for 1mn after we > resume before autosuspending again. But I want to fix obvious > problems first. would agree with that as well.
acpiac(4): refresh status after resume
So I have this diff for apmd -z/-Z that uses APM_POWER_CHANGE events to trigger autosuspend. It works fine except for one glitch: if I plug the AC cable and then resume, apmd will receive another APM_POWER_CHANGE event and read the power info only to find that the AC is *unplugged*. So apmd happily suspends my system again. If I resume once more, the AC status is correctly detected and apmd(8) doesn't suspend the system again. What happens is that acpibat_notify runs because of ACPIDEV_POLL, it grabs battery data and sends an APM_POWER_CHANGE event to apmd. At this point apmd may see out of date data from acpiac(4). acpi_sleep_task later forces a refresh of (in order) acpiac(4), acpibat(4) and acpisbs(4), but in my use case it's too late, the window with stale acpiac(4) data is too long. The diff below refreshes AC status with notifications at DVACT_WAKEUP time. Is is correct that DVACT_WAKEUP handlers will always run before the ACPI task queue is processed? "No" seems unlikely but I'd rather ask... I hear we prefer running ACPI code in its dedicated thread but there are other drivers in dev/acpi that run ACPI code in DVACT_WAKEUP, so I'm assuming it is fine. :) There are probably many ways to tackle this problem, from having userland ignore stale data after a resume to tweaking acpibat(4) to stop/restart/skip the ACPIDEV_POLL loop, but all of them look hackish/undoable so far. Thoughts? oks? Index: acpiac.c === RCS file: /d/cvs/src/sys/dev/acpi/acpiac.c,v retrieving revision 1.31 diff -u -p -p -u -r1.31 acpiac.c --- acpiac.c1 Jul 2018 19:40:49 - 1.31 +++ acpiac.c25 Jan 2020 18:33:15 - @@ -33,13 +33,18 @@ int acpiac_match(struct device *, void *, void *); void acpiac_attach(struct device *, struct device *, void *); +int acpiac_activate(struct device *, int); int acpiac_notify(struct aml_node *, int, void *); void acpiac_refresh(void *); int acpiac_getsta(struct acpiac_softc *); struct cfattach acpiac_ca = { - sizeof(struct acpiac_softc), acpiac_match, acpiac_attach + sizeof(struct acpiac_softc), + acpiac_match, + acpiac_attach, + NULL, + acpiac_activate, }; struct cfdriver acpiac_cd = { @@ -92,6 +97,21 @@ acpiac_attach(struct device *parent, str acpiac_notify, sc, ACPIDEV_NOPOLL); } +int +acpiac_activate(struct device *self, int act) +{ + struct acpiac_softc *sc = (struct acpiac_softc *)self; + + switch (act) { + case DVACT_WAKEUP: + acpiac_refresh(sc); + dnprintf(10, "A/C status: %d\n", sc->sc_ac_stat); + break; + } + + return (0); +} + void acpiac_refresh(void *arg) { @@ -99,7 +119,6 @@ acpiac_refresh(void *arg) acpiac_getsta(sc); sc->sc_sens[0].value = sc->sc_ac_stat; - acpi_record_event(sc->sc_acpi, APM_POWER_CHANGE); } int @@ -140,6 +159,7 @@ acpiac_notify(struct aml_node *node, int /* FALLTHROUGH */ case 0x80: acpiac_refresh(sc); + acpi_record_event(sc->sc_acpi, APM_POWER_CHANGE); dnprintf(10, "A/C status: %d\n", sc->sc_ac_stat); break; } -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
apmd: fix autoaction timeout
The diff below improves the way apmd -z/-Z may trigger. I think the current behavior is bogus, incrementing and checking apmtimeout like this doesn't make much sense. Here's a proposal: - on APM_POWER_CHANGE events, check the battery level and trigger autoaction if needed. This should be enough to make autoaction just work with drivers like acpibat(4). - on kevent timeout (10mn by default now, maybe too long), also check the battery level and suspend if needed. This should be useful only if your battery driver doesn't send any APM_POWER_CHANGE event. While here I also tweaked the warning. Some more context: - a subsequent diff would reorder the code to handle similarly the "!rv" and "ev->ident == ctl_fd" paths - I think we want some throttling mechanism, like wait for 1mn after we resume before autosuspending again. But I want to fix obvious problems first. - if battery is still lower than your autoaction limit, your system might go back to sleep once if you attempt a resume after plugging your AC cable. Another glitch, another mail to tech@. Thoughts? oks? Index: apmd.c === RCS file: /cvs/src/usr.sbin/apmd/apmd.c,v retrieving revision 1.91 diff -u -p -r1.91 apmd.c --- apmd.c 2 Nov 2019 00:41:36 - 1.91 +++ apmd.c 25 Jan 2020 18:05:08 - @@ -380,7 +380,6 @@ main(int argc, char *argv[]) int noacsleep = 0; struct timespec ts = {TIMO, 0}, sts = {0, 0}; struct apm_power_info pinfo; - time_t apmtimeout = 0; const char *sockname = _PATH_APM_SOCKET; const char *errstr; int kq, nchanges; @@ -502,13 +501,10 @@ main(int argc, char *argv[]) sts = ts; - apmtimeout += 1; if ((rv = kevent(kq, NULL, 0, ev, 1, )) == -1) break; - if (apmtimeout >= ts.tv_sec) { - apmtimeout = 0; - + if (!rv) { /* wakeup for timeout: take status */ powerbak = power_status(ctl_fd, 0, ); if (powerstatus != powerbak) { @@ -519,8 +515,8 @@ main(int argc, char *argv[]) if (!powerstatus && autoaction && autolimit > (int)pinfo.battery_life) { logmsg(LOG_NOTICE, - "estimated battery life %d%%, " - "autoaction limit set to %d%% .", + "estimated battery life %d%%" + " below configured limit %d%%", pinfo.battery_life, autolimit ); @@ -530,10 +526,8 @@ main(int argc, char *argv[]) else hibernate(ctl_fd); } - } - - if (!rv) continue; + } if (ev->ident == ctl_fd) { suspends = standbys = hibernates = resumes = 0; @@ -575,6 +569,19 @@ main(int argc, char *argv[]) if (powerstatus != powerbak) { powerstatus = powerbak; powerchange = 1; + } + + if (!powerstatus && autoaction && + autolimit > (int)pinfo.battery_life) { + logmsg(LOG_NOTICE, + "estimated battery life %d%%" + " below configured limit %d%%", + pinfo.battery_life, autolimit); + + if (autoaction == AUTO_SUSPEND) + suspends++; + else + hibernates++; } break; default: -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
acpisbs(4): send APM events
acpisbs(4) should send events to userland (apmd) whenever it refreshes its data, just like acpibat(4). I have no hw to test this, I'd welcome a runtime check with apmd -d. ok? Index: acpisbs.c === RCS file: /d/cvs/src/sys/dev/acpi/acpisbs.c,v retrieving revision 1.8 diff -u -p -p -u -r1.8 acpisbs.c --- acpisbs.c 9 May 2019 18:29:25 - 1.8 +++ acpisbs.c 25 Jan 2020 17:28:10 - @@ -28,6 +28,8 @@ #include #include +#include + #include #include #include @@ -377,6 +379,7 @@ acpisbs_notify(struct aml_node *node, in if (diff.tv_sec > ACPISBS_POLL_FREQ) { acpisbs_read(sc); acpisbs_refresh_sensors(sc); + acpi_record_event(sc->sc_acpi, APM_POWER_CHANGE); getmicrouptime(>sc_lastpoll); } break; -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
Re: apmd poll every minute
On Fri, Jan 24 2020, "Ted Unangst" wrote: > Sometimes (particuarly if you are using apmd -z) the default polling interval > of 10 minutes is a bit lazy and we fail to respond to low battery situations > before they become no battery situations. > > Perhaps something smarter could be done, but the simplest change is to reduce > the default polling interval to one minute. This is still rather slow, so as > to not introduce unnecessary load on the system, but should make it more > responsive to changing conditions. Hah, I'm poking at this since yesterday. Your change is only useful if you have a battery driver that doesn't notify you often enough. acpibat(4) uses ACPIDEV_POLL and sends apmd a message every 10 seconds. That's way more than enough for apmd to act. If you use acpisbs(4) or another battery driver that doesn't send any event to userland, you might find the apmd poll timeout a tad long. But I'm not sure this is the way to solve it. apmd -z/-Z is mostly broken if you don't use -t and a very short poll timeout, but this can easily be improved. Diffs are coming. -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
Add #define for RFC8622 IPTOS_DSCP_LE codepoint
Hi, This adds a #define for the "lower effort" DSCP code point specified by https://tools.ietf.org/html/rfc8622 People have asked to be able to use this OpenSSH for "don't care" traffic. ok? Index: sys/netinet/ip.h === RCS file: /cvs/src/sys/netinet/ip.h,v retrieving revision 1.18 diff -u -p -r1.18 ip.h --- sys/netinet/ip.h8 Aug 2017 18:25:31 - 1.18 +++ sys/netinet/ip.h25 Jan 2020 12:34:27 - @@ -98,6 +98,7 @@ struct ip { * Definitions for DiffServ Codepoints as per RFC2474 */ #defineIPTOS_DSCP_CS0 0x00 +#defineIPTOS_DSCP_LE 0x01 #defineIPTOS_DSCP_CS1 0x20 #defineIPTOS_DSCP_AF11 0x28 #defineIPTOS_DSCP_AF12 0x30