Re: Stairstep mouse motion
On Sat, Oct 26, 2013 at 10:13:11PM +0600, Alexandr Shadchin wrote: On Fri, Oct 25, 2013 at 11:41:25AM +0100, Edd Barrett wrote: On Thu, Oct 24, 2013 at 10:33:22PM +0300, Henri Kemppainen wrote: What happens when priv-swap_axes is set, and the ax ay branch is taken along with the wsWheelEmuFilterMotion() branch. Following continue another event is processed and now the axes are swapped again (ax and ay were not reset after use) and then what? Not very likely I know. Ah, yes, there is the possibility of posting an inconsistent pointer sample in this case. Perhaps we should only update the old_ax/old_ay if the wsWheelEmuFilterMotion branch is not taken? What do you think? And yes, this is a very very unlikely case. You could argue it wouldn't matter even if it did happen. -- Best Regards Edd Barrett http://www.theunixzoo.co.uk Alternative solution without extra magic (need rebuild kernel). Before (on example pms(4)): * user move mouse * pms(4) read state mouse and process it * pms(4) send dx, dy and buttons in wscons * wscons generate simple events * ws(4) reads one event and process it immediately After applying diff: * user move mouse * pms(4) read state mouse and process it * pms(4) send dx, dy and buttons in wscons * wscons generate simple events and adds SYNC event * ws(4) reads events until it receives SYNC, and only then begins processing Tested on mouse. Comments ? PS: synaptics(4) is working on a similar basis -- Alexandr Shadchin I've tested this diff with some hours of QuakeWorld, an old and very fast/demanding FPS game. Works well. This staircase fix + KMS have improved these types of games on OpenBSD a lot. However, mouse input still isn't there yet, it still feels slightly delayed and not precise enough compared to running the same game and game client on Linux. This is only subtle and will most likely not be noticed without playing quite a lot though. Modern Quake engines rely on high sleep granuality so I always have to rip out any usleep from the clients since in OpenBSD atm you can't sleep below tic rate (roughly 1/100 sec on my machine) AFAIK. This may add to the aforementioned felt latency on input. Alf OpenBSD 5.4-current (GENERIC.MP) #0: Tue Oct 29 14:32:26 CET 2013 r...@obsd.rechners.lemarit.com:/usr/src/sys/arch/amd64/compile/GENERIC.MP real mem = 8555986944 (8159MB) avail mem = 8320094208 (7934MB) mainbus0 at root bios0 at mainbus0: SMBIOS rev. 2.4 @ 0xf0100 (37 entries) bios0: vendor Award Software International, Inc. version F9 date 03/21/2012 bios0: Gigabyte Technology Co., Ltd. PH67A-UD3-B3 acpi0 at bios0: rev 0 acpi0: sleep states S0 S3 S4 S5 acpi0: tables DSDT FACP MSDM HPET MCFG ASPT SSPT EUDS MATS TAMG APIC SSDT MATS acpi0: wakeup devices PEX0(S5) PEX1(S5) PEX2(S5) PEX3(S5) PEX4(S5) PEX5(S5) PEX6(S5) PEX7(S5) HUB0(S5) UAR1(S3) USBE(S3) USE2(S3) AZAL(S5) PCI0(S5) acpitimer0 at acpi0: 3579545 Hz, 24 bits acpihpet0 at acpi0: 14318179 Hz acpimcfg0 at acpi0 addr 0xf400, bus 0-63 acpimadt0 at acpi0 addr 0xfee0: PC-AT compat cpu0 at mainbus0: apid 0 (boot processor) cpu0: Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz, 3396.09 MHz cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,NXE,LONG,LAHF,PERF,ITSC cpu0: 256KB 64b/line 8-way L2 cache cpu0: smt 0, core 0, package 0 cpu0: apic clock running at 99MHz cpu0: mwait min=64, max=64, C-substates=0.2.1.1.0, IBE cpu1 at mainbus0: apid 2 (application processor) cpu1: Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz, 3395.56 MHz cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,NXE,LONG,LAHF,PERF,ITSC cpu1: 256KB 64b/line 8-way L2 cache cpu1: smt 0, core 1, package 0 cpu2 at mainbus0: apid 4 (application processor) cpu2: Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz, 3395.56 MHz cpu2: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,NXE,LONG,LAHF,PERF,ITSC cpu2: 256KB 64b/line 8-way L2 cache cpu2: smt 0, core 2, package 0 cpu3 at mainbus0: apid 6 (application processor) cpu3: Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz, 3395.56 MHz cpu3: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,NXE,LONG,LAHF,PERF,ITSC cpu3: 256KB 64b/line 8-way L2 cache cpu3: smt 0, core 3, package 0
Re: Stairstep mouse motion
On Tue, Oct 29, 2013 at 11:07:29PM +0600, Alexandr Shadchin wrote: Look good to me. However I've a concern about compatibility with NetBSD. The kernel change should be documented in the commit message for xf86-input-ws so that they can catch up with the kernel change before they update xf86-input-ws... Update diff (add small hack for NetBSD). Having spent ten minutes scribbling in xournal using my stylus, I can say that this appears to work well. Diagonal lines are smooth even when drawn fast. ws.c is looking much tidier too. If the others are happy with the kernel portion of your diff, then I reckon this is good to go in. -- Best Regards Edd Barrett http://www.theunixzoo.co.uk
Re: Stairstep mouse motion
On Tue, Oct 29, 2013 at 11:07:29PM +0600, Alexandr Shadchin wrote: Update diff (add small hack for NetBSD). Thanks. This (plus the kernel diff) is ok matthieu@. -- Alexandr Shadchin Index: ws.c === RCS file: /cvs/xenocara/driver/xf86-input-ws/src/ws.c,v retrieving revision 1.58 diff -u -p -r1.58 ws.c --- ws.c 20 Jul 2013 13:24:50 - 1.58 +++ ws.c 29 Oct 2013 16:57:05 - @@ -428,13 +428,6 @@ wsDeviceOn(DeviceIntPtr pWS) } } } - priv-buffer = XisbNew(pInfo-fd, - sizeof(struct wscons_event) * NUMEVENTS); - if (priv-buffer == NULL) { - xf86IDrvMsg(pInfo, X_ERROR, cannot alloc xisb buffer\n); - wsClose(pInfo); - return !Success; - } xf86AddEnabledDevice(pInfo); wsmbEmuOn(pInfo); pWS-public.on = TRUE; @@ -462,170 +455,157 @@ wsDeviceOff(DeviceIntPtr pWS) xf86RemoveEnabledDevice(pInfo); wsClose(pInfo); } - if (priv-buffer) { - XisbFree(priv-buffer); - priv-buffer = NULL; - } pWS-public.on = FALSE; } -static void -wsReadInput(InputInfoPtr pInfo) +static Bool +wsReadEvent(InputInfoPtr pInfo, struct wscons_event *event) { - WSDevicePtr priv = (WSDevicePtr)pInfo-private; - static struct wscons_event eventList[NUMEVENTS]; - int n, c, dx, dy; - struct wscons_event *event = eventList; - unsigned char *pBuf; - - XisbBlockDuration(priv-buffer, -1); - pBuf = (unsigned char *)eventList; - n = 0; - while (n sizeof(eventList) (c = XisbRead(priv-buffer)) = 0) { - pBuf[n++] = (unsigned char)c; + Bool rc = TRUE; + ssize_t len; + + len = read(pInfo-fd, event, sizeof(struct wscons_event)); + if (len = 0) { + if (errno != EAGAIN) + xf86IDrvMsg(pInfo, X_ERROR, read error %s\n, + strerror(errno)); + rc = FALSE; + } else if (len != sizeof(struct wscons_event)) { + xf86IDrvMsg(pInfo, X_ERROR, + read error, invalid number of bytes\n); + rc = FALSE; } - if (n == 0) - return; + return rc; +} - dx = dy = 0; - n /= sizeof(struct wscons_event); - while (n--) { - int buttons = priv-lastButtons; - int newdx = 0, newdy = 0, dz = 0, dw = 0, ax = 0, ay = 0; - int zbutton = 0, wbutton = 0; +static Bool +wsReadHwState(InputInfoPtr pInfo, wsHwState *hw) +{ + WSDevicePtr priv = (WSDevicePtr)pInfo-private; + struct wscons_event event; + + bzero(hw, sizeof(wsHwState)); + + hw-buttons = priv-lastButtons; + hw-ax = priv-old_ax; + hw-ay = priv-old_ay; - switch (event-type) { + while (wsReadEvent(pInfo, event)) { + switch (event.type) { case WSCONS_EVENT_MOUSE_UP: - buttons = ~(1 event-value); - DBG(4, ErrorF(Button %d up %x\n, event-value, - buttons)); + hw-buttons = ~(1 event.value); + DBG(4, ErrorF(Button %d up %x\n, event.value, + hw-buttons)); break; case WSCONS_EVENT_MOUSE_DOWN: - buttons |= (1 event-value); - DBG(4, ErrorF(Button %d down %x\n, event-value, - buttons)); + hw-buttons |= (1 event.value); + DBG(4, ErrorF(Button %d down %x\n, event.value, + hw-buttons)); break; case WSCONS_EVENT_MOUSE_DELTA_X: - if (!dx) - dx = event-value; - else - newdx = event-value; - DBG(4, ErrorF(Relative X %d\n, event-value)); + hw-dx = event.value; + DBG(4, ErrorF(Relative X %d\n, event.value)); break; case WSCONS_EVENT_MOUSE_DELTA_Y: - if (!dy) - dy = -event-value; - else - newdy = -event-value; - DBG(4, ErrorF(Relative Y %d\n, event-value)); + hw-dy = -event.value; + DBG(4, ErrorF(Relative Y %d\n, event.value)); + break; + case WSCONS_EVENT_MOUSE_DELTA_Z: + hw-dz = event.value; + DBG(4, ErrorF(Relative Z %d\n, event.value)); + break; + case WSCONS_EVENT_MOUSE_DELTA_W: + hw-dw = event.value; + DBG(4, ErrorF(Relative W %d\n,
convert crypto queue to the task(9) api
Tested on amd64 SP and MP, i386 SP so far. sparc64 MP test is in progress. I've also tested the crypto(4) interface (doesn't use queue) so softraid should work as well. ok? diff --git sys/crypto/crypto.c sys/crypto/crypto.c index 7df0c435..fbdcd97 100644 --- sys/crypto/crypto.c +++ sys/crypto/crypto.c @@ -34,11 +34,11 @@ struct cryptocap *crypto_drivers = NULL; int crypto_drivers_num = 0; struct pool cryptop_pool; struct pool cryptodesc_pool; -struct workq *crypto_workq; +struct taskq *crypto_taskq; /* * Create a new session. */ int @@ -414,26 +414,26 @@ crypto_dispatch(struct cryptop *crp) hid = (crp-crp_sid 32) 0x; if (hid crypto_drivers_num) crypto_drivers[hid].cc_queued++; splx(s); - if (crypto_workq) { - workq_queue_task(crypto_workq, crp-crp_wqt, 0, - (workq_fn)crypto_invoke, crp, NULL); + if (crypto_taskq) { + task_set(crp-crp_task, (void (*))crypto_invoke, crp, NULL); + task_add(crypto_taskq, crp-crp_task); } else { crypto_invoke(crp); } return 0; } int crypto_kdispatch(struct cryptkop *krp) { - if (crypto_workq) { - workq_queue_task(crypto_workq, krp-krp_wqt, 0, - (workq_fn)crypto_kinvoke, krp, NULL); + if (crypto_taskq) { + task_set(krp-krp_task, (void (*))crypto_kinvoke, krp, NULL); + task_add(crypto_taskq, krp-krp_task); } else { crypto_kinvoke(krp); } return 0; @@ -616,11 +616,11 @@ crypto_getreq(int num) } void crypto_init(void) { - crypto_workq = workq_create(crypto, 1, IPL_HIGH); + crypto_taskq = taskq_create(crypto, 1, IPL_HIGH); pool_init(cryptop_pool, sizeof(struct cryptop), 0, 0, 0, cryptop, NULL); pool_init(cryptodesc_pool, sizeof(struct cryptodesc), 0, 0, 0, cryptodesc, NULL); @@ -635,23 +635,24 @@ crypto_done(struct cryptop *crp) crp-crp_flags |= CRYPTO_F_DONE; if (crp-crp_flags CRYPTO_F_NOQUEUE) { /* not from the crypto queue, wakeup the userland process */ crp-crp_callback(crp); } else { - workq_queue_task(crypto_workq, crp-crp_wqt, 0, - (workq_fn)crp-crp_callback, crp, NULL); + task_set(crp-crp_task, (void (*))crp-crp_callback, + crp, NULL); + task_add(crypto_taskq, crp-crp_task); } } /* * Invoke the callback on behalf of the driver. */ void crypto_kdone(struct cryptkop *krp) { - workq_queue_task(crypto_workq, krp-krp_wqt, 0, - (workq_fn)krp-krp_callback, krp, NULL); + task_set(krp-krp_task, (void (*))krp-krp_callback, krp, NULL); + task_add(crypto_taskq, krp-krp_task); } int crypto_getfeat(int *featp) { diff --git sys/crypto/cryptodev.h sys/crypto/cryptodev.h index 4f87046..4f732f9 100644 --- sys/crypto/cryptodev.h +++ sys/crypto/cryptodev.h @@ -51,11 +51,11 @@ #ifndef _CRYPTO_CRYPTO_H_ #define _CRYPTO_CRYPTO_H_ #include sys/ioccom.h -#include sys/workq.h +#include sys/task.h /* Some initial values */ #define CRYPTO_DRIVERS_INITIAL 4 #define CRYPTO_DRIVERS_MAX 128 #define CRYPTO_SW_SESSIONS 32 @@ -158,11 +158,11 @@ struct cryptodesc { struct cryptodesc *crd_next; }; /* Structure describing complete operation */ struct cryptop { - struct workq_task crp_wqt; + struct task crp_task; u_int64_t crp_sid;/* Session ID */ int crp_ilen; /* Input data total length */ int crp_olen; /* Result total length */ int crp_alloctype; /* Type of buf to allocate if needed */ @@ -228,11 +228,11 @@ struct crypt_kop { #define CRF_DSA_SIGN (1 CRK_DSA_SIGN) #define CRF_DSA_VERIFY (1 CRK_DSA_VERIFY) #define CRF_DH_COMPUTE_KEY (1 CRK_DH_COMPUTE_KEY) struct cryptkop { - struct workq_task krp_wqt; + struct task krp_task; u_int krp_op; /* ie. CRK_MOD_EXP or other */ u_int krp_status; /* return status */ u_short krp_iparams;/* # of input parameters */ u_short krp_oparams;/* # of output parameters */
Re: convert crypto queue to the task(9) api
On Wed, Oct 30, 2013 at 14:58 +0100, Mike Belopuhov wrote: Tested on amd64 SP and MP, i386 SP so far. sparc64 MP test is in progress. I've also tested the crypto(4) interface (doesn't use queue) so softraid should work as well. sparc64 test is done. on a side note, that IPL_HIGH can be safely converted to IPL_VM since crypto code itself uses splvm (which is also rather pointless because hw crypto uses IPL_NET and mbuf allocation code will bump IPL itself anyways). i have just tested IPL_VM taskq on the aforementioned machines. ok? diff --git sys/crypto/crypto.c sys/crypto/crypto.c index 7df0c435..fbdcd97 100644 --- sys/crypto/crypto.c +++ sys/crypto/crypto.c @@ -34,11 +34,11 @@ struct cryptocap *crypto_drivers = NULL; int crypto_drivers_num = 0; struct pool cryptop_pool; struct pool cryptodesc_pool; -struct workq *crypto_workq; +struct taskq *crypto_taskq; /* * Create a new session. */ int @@ -414,26 +414,26 @@ crypto_dispatch(struct cryptop *crp) hid = (crp-crp_sid 32) 0x; if (hid crypto_drivers_num) crypto_drivers[hid].cc_queued++; splx(s); - if (crypto_workq) { - workq_queue_task(crypto_workq, crp-crp_wqt, 0, - (workq_fn)crypto_invoke, crp, NULL); + if (crypto_taskq) { + task_set(crp-crp_task, (void (*))crypto_invoke, crp, NULL); + task_add(crypto_taskq, crp-crp_task); } else { crypto_invoke(crp); } return 0; } int crypto_kdispatch(struct cryptkop *krp) { - if (crypto_workq) { - workq_queue_task(crypto_workq, krp-krp_wqt, 0, - (workq_fn)crypto_kinvoke, krp, NULL); + if (crypto_taskq) { + task_set(krp-krp_task, (void (*))crypto_kinvoke, krp, NULL); + task_add(crypto_taskq, krp-krp_task); } else { crypto_kinvoke(krp); } return 0; @@ -616,11 +616,11 @@ crypto_getreq(int num) } void crypto_init(void) { - crypto_workq = workq_create(crypto, 1, IPL_HIGH); + crypto_taskq = taskq_create(crypto, 1, IPL_HIGH); pool_init(cryptop_pool, sizeof(struct cryptop), 0, 0, 0, cryptop, NULL); pool_init(cryptodesc_pool, sizeof(struct cryptodesc), 0, 0, 0, cryptodesc, NULL); @@ -635,23 +635,24 @@ crypto_done(struct cryptop *crp) crp-crp_flags |= CRYPTO_F_DONE; if (crp-crp_flags CRYPTO_F_NOQUEUE) { /* not from the crypto queue, wakeup the userland process */ crp-crp_callback(crp); } else { - workq_queue_task(crypto_workq, crp-crp_wqt, 0, - (workq_fn)crp-crp_callback, crp, NULL); + task_set(crp-crp_task, (void (*))crp-crp_callback, + crp, NULL); + task_add(crypto_taskq, crp-crp_task); } } /* * Invoke the callback on behalf of the driver. */ void crypto_kdone(struct cryptkop *krp) { - workq_queue_task(crypto_workq, krp-krp_wqt, 0, - (workq_fn)krp-krp_callback, krp, NULL); + task_set(krp-krp_task, (void (*))krp-krp_callback, krp, NULL); + task_add(crypto_taskq, krp-krp_task); } int crypto_getfeat(int *featp) { diff --git sys/crypto/cryptodev.h sys/crypto/cryptodev.h index 4f87046..4f732f9 100644 --- sys/crypto/cryptodev.h +++ sys/crypto/cryptodev.h @@ -51,11 +51,11 @@ #ifndef _CRYPTO_CRYPTO_H_ #define _CRYPTO_CRYPTO_H_ #include sys/ioccom.h -#include sys/workq.h +#include sys/task.h /* Some initial values */ #define CRYPTO_DRIVERS_INITIAL 4 #define CRYPTO_DRIVERS_MAX 128 #define CRYPTO_SW_SESSIONS 32 @@ -158,11 +158,11 @@ struct cryptodesc { struct cryptodesc *crd_next; }; /* Structure describing complete operation */ struct cryptop { - struct workq_task crp_wqt; + struct task crp_task; u_int64_t crp_sid;/* Session ID */ int crp_ilen; /* Input data total length */ int crp_olen; /* Result total length */ int crp_alloctype; /* Type of buf to allocate if needed */ @@ -228,11 +228,11 @@ struct crypt_kop { #define CRF_DSA_SIGN (1 CRK_DSA_SIGN) #define CRF_DSA_VERIFY (1 CRK_DSA_VERIFY) #define CRF_DH_COMPUTE_KEY (1 CRK_DH_COMPUTE_KEY) struct cryptkop { - struct workq_task krp_wqt; + struct task krp_task; u_int krp_op; /* ie. CRK_MOD_EXP or other */ u_int krp_status; /* return status */ u_short krp_iparams;/* # of input parameters */ u_short krp_oparams;/* # of output parameters */
Re: in6_leavegroup work queue
On Fri, Oct 18, 2013 at 01:00:25PM +0200, Martin Pieuchot wrote: On 18/10/13(Fri) 12:45, Alexander Bluhm wrote: Ethernet drivers connected via USB might sleep when their multicast group filter is modified. Unfortunately this happens from softclock or softnet interrupt when IPv6 decides to unconfigure its addresses automatically. An obvious solution is to use a work queue. I have put the workq storage into struct in6_multi_mship. That requires to include sys/workq.h before compiling this struct. One problem with a work queue is that you cannot guarantee the interface will still be here when the task will be scheduled, so passing a pointer might not be a good idea. That is why I wanted to change the if_get() API to use unique index for each interface... But maybe there's another solution at this problem than using a workq... Now I use the if_index to detect that the interface is gone. I this a better approach? bluhm Index: netinet6/in6.c === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6.c,v retrieving revision 1.122 diff -u -p -u -p -r1.122 in6.c --- netinet6/in6.c 24 Oct 2013 11:20:18 - 1.122 +++ netinet6/in6.c 30 Oct 2013 15:01:20 - @@ -124,6 +124,7 @@ int in6_lifaddr_ioctl(struct socket *, u int in6_ifinit(struct ifnet *, struct in6_ifaddr *, int); void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *); void in6_ifloop_request(int, struct ifaddr *); +void in6_leavegroup_task(void *, void *); const struct sockaddr_in6 sa6_any = { sizeof(sa6_any), AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0 @@ -1777,16 +1778,18 @@ in6_delmulti(struct in6_multi *in6m) ifafree(in6m-in6m_ia-ia_ifa); /* release reference */ } - /* -* Notify the network driver to update its multicast -* reception filter. -*/ - bzero(ifr.ifr_addr, sizeof(struct sockaddr_in6)); - ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6); - ifr.ifr_addr.sin6_family = AF_INET6; - ifr.ifr_addr.sin6_addr = in6m-in6m_addr; - (*in6m-in6m_ifp-if_ioctl)(in6m-in6m_ifp, - SIOCDELMULTI, (caddr_t)ifr); + if (in6m-in6m_ifp != NULL) { + /* +* Notify the network driver to update its multicast +* reception filter. +*/ + bzero(ifr.ifr_addr, sizeof(struct sockaddr_in6)); + ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6); + ifr.ifr_addr.sin6_family = AF_INET6; + ifr.ifr_addr.sin6_addr = in6m-in6m_addr; + (*in6m-in6m_ifp-if_ioctl)(in6m-in6m_ifp, + SIOCDELMULTI, (caddr_t)ifr); + } free(in6m, M_IPMADDR); } splx(s); @@ -1814,11 +1817,26 @@ in6_joingroup(struct ifnet *ifp, struct int in6_leavegroup(struct in6_multi_mship *imm) { - if (imm-i6mm_maddr) - in6_delmulti(imm-i6mm_maddr); - free(imm, M_IPMADDR); + workq_queue_task(NULL, imm-wqt, 0, in6_leavegroup_task, imm, + (void *)(unsigned long)imm-i6mm_maddr-in6m_ifp-if_index); + else + free(imm, M_IPMADDR); return 0; +} + +void +in6_leavegroup_task(void *arg1, void *arg2) +{ + struct in6_multi_mship *imm = arg1; + unsigned int index = (unsigned long)arg2; + + /* If interface has been be freed, avoid call to if_ioctl(). */ + if (if_get(index) != imm-i6mm_maddr-in6m_ifp) + imm-i6mm_maddr-in6m_ifp = NULL; + + in6_delmulti(imm-i6mm_maddr); + free(imm, M_IPMADDR); } /* Index: netinet6/in6_var.h === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6_var.h,v retrieving revision 1.44 diff -u -p -u -p -r1.44 in6_var.h --- netinet6/in6_var.h 24 Oct 2013 11:31:43 - 1.44 +++ netinet6/in6_var.h 30 Oct 2013 15:01:20 - @@ -64,6 +64,8 @@ #ifndef _NETINET6_IN6_VAR_H_ #define _NETINET6_IN6_VAR_H_ +#include sys/workq.h + /* * Interface address, Internet version. One of these structures * is allocated for each interface with an Internet address. @@ -480,6 +482,7 @@ do { \ * belongs to. */ struct in6_multi_mship { + struct workq_task wqt; /* Allow network driver to sleep */ struct in6_multi *i6mm_maddr; /* Multicast address pointer */ LIST_ENTRY(in6_multi_mship) i6mm_chain; /* multicast options chain */ };
Re: HFSC queue pusher
On Mon, Oct 28, 2013 at 01:55:16AM +0100, Martin Pelikan wrote: Hi, if you noticed weak newqueue performance, it was because one component of it was missing. After a discussion with claudio I made this diff, which makes a timeout per HFSC-enabled interface and pushes the data every hardclock tick, similarly to what oldtbr_timeout() used to do. This way, in the future, we can: - Replace splnet() with mtx_enter(ifp-lock) directly (here). - Replace the current coarse 1/HZ timing with a proper high resolution one. This should be done directly in hfsc_dequeue by setting the exact value (or maybe slightly more, to accumulate more dequeues into one if_start call) instead of just 1 tick all the time. The timing details will probably become clearer when we switch from TAILQs to RB trees and stop spending huge amounts of time going back and forth over all of the active classes. This diff applies to our current tree, to make it work with unlimited v3 diff, you obviously need to substitute some -'s for .'s. comments? ok? Diff itself is OK. I think there are other options to get higher resolution tickers by running the ticker in something that is called more often (for example the softintr handler of the network stack). But something like this needed and should go in. -- Martin Pelikan Index: hfsc.c === RCS file: /cvs/src/sys/net/hfsc.c,v retrieving revision 1.1 diff -u -p -r1.1 hfsc.c --- hfsc.c12 Oct 2013 11:39:17 - 1.1 +++ hfsc.c27 Oct 2013 22:53:50 - @@ -74,6 +74,7 @@ int hfsc_addq(struct hfsc_class *, str struct mbuf *hfsc_getq(struct hfsc_class *); struct mbuf *hfsc_pollq(struct hfsc_class *); void hfsc_purgeq(struct hfsc_class *); +void hfsc_deferred(void *); void hfsc_update_cfmin(struct hfsc_class *); void hfsc_set_active(struct hfsc_class *, int); void hfsc_set_passive(struct hfsc_class *); @@ -140,6 +141,9 @@ hfsc_attach(struct ifnet *ifp) hif-hif_eligible = hfsc_ellist_alloc(); hif-hif_ifq = (struct ifqueue *)ifp-if_snd; /* XXX cast temp */ ifp-if_snd.ifq_hfsc = hif; + timeout_set(hif-hif_defer, hfsc_deferred, ifp); + /* XXX HRTIMER don't schedule it yet, only when some packets wait. */ + timeout_add(hif-hif_defer, 1); return (0); } @@ -147,6 +151,7 @@ hfsc_attach(struct ifnet *ifp) int hfsc_detach(struct ifnet *ifp) { + timeout_del(ifp-if_snd.ifq_hfsc-hif_defer); free(ifp-if_snd.ifq_hfsc, M_DEVBUF); ifp-if_snd.ifq_hfsc = NULL; @@ -557,6 +562,7 @@ hfsc_dequeue(struct ifqueue *ifq, int re cl = tcl; } + /* XXX HRTIMER plan hfsc_deferred precisely here. */ if (cl == NULL) return (NULL); } @@ -601,6 +607,21 @@ hfsc_dequeue(struct ifqueue *ifq, int re } return (m); +} + +void +hfsc_deferred(void *arg) +{ + struct ifnet *ifp = arg; + int s; + + s = splnet(); + if (HFSC_ENABLED(ifp-if_snd) !IFQ_IS_EMPTY(ifp-if_snd)) + if_start(ifp); + splx(s); + + /* XXX HRTIMER nearest virtual/fit time is likely less than 1/HZ. */ + timeout_add(ifp-if_snd.ifq_hfsc-hif_defer, 1); } int Index: hfsc.h === RCS file: /cvs/src/sys/net/hfsc.h,v retrieving revision 1.1 diff -u -p -r1.1 hfsc.h --- hfsc.h12 Oct 2013 11:39:17 - 1.1 +++ hfsc.h27 Oct 2013 22:53:50 - @@ -33,6 +33,8 @@ #ifndef _HFSC_H_ #define _HFSC_H_ +#include sys/timeout.h + /* hfsc class flags */ #define HFSC_RED0x0001 /* use RED */ #define HFSC_ECN0x0002 /* use RED/ECN */ @@ -242,6 +244,7 @@ struct hfsc_if { u_int hif_classid;/* class id sequence number */ hfsc_ellist_t *hif_eligible;/* eligible list */ + struct timeout hif_defer; /* for queues that weren't ready */ }; #define HFSC_CLK_SHIFT 8 -- :wq Claudio
Re: kernel route 64 bit expire time
On Tue, Oct 15, 2013 at 12:43:16AM +0200, Alexander Bluhm wrote: Convert the route expire timestamp in kernel and routing message to 64 bit. Add a small compatibility layer that allows to set routes with old user land and new kernel. You can still config addresses with old ifconfig and new kernel. I have increased the compatibility layer, route get also works in this setup. dhclient still hangs as I have do not generate old messages for interface address changes. I would like to get that in as it is. ok? bluhm Index: net/route.h === RCS file: /data/mirror/openbsd/cvs/src/sys/net/route.h,v retrieving revision 1.82 diff -u -p -u -p -r1.82 route.h --- net/route.h 24 Oct 2013 18:50:16 - 1.82 +++ net/route.h 30 Oct 2013 16:30:40 - @@ -48,10 +48,9 @@ */ struct rt_kmetrics { u_int64_t rmx_pksent; /* packets sent using this route */ + int64_t rmx_expire; /* lifetime for route, e.g. redirect */ u_int rmx_locks; /* Kernel must leave these values */ u_int rmx_mtu;/* MTU for this path */ - u_int rmx_expire; /* lifetime for route, e.g. redirect */ - u_int rmx_pad; }; /* @@ -59,9 +58,9 @@ struct rt_kmetrics { */ struct rt_metrics { u_int64_t rmx_pksent; /* packets sent using this route */ + int64_t rmx_expire; /* lifetime for route, e.g. redirect */ u_int rmx_locks; /* Kernel must leave these values */ u_int rmx_mtu;/* MTU for this path */ - u_int rmx_expire; /* lifetime for route, e.g. redirect */ u_int rmx_refcnt; /* # references hold */ /* some apps may still need these no longer used metrics */ u_int rmx_hopcount; /* max hops expected */ @@ -70,6 +69,7 @@ struct rt_metrics { u_int rmx_ssthresh; /* outbound gateway buffer limit */ u_int rmx_rtt;/* estimated round trip time */ u_int rmx_rttvar; /* estimated rtt variance */ + u_int rmx_pad; }; /* @@ -207,7 +207,47 @@ struct rt_msghdr { /* overload no longer used field */ #define rtm_usertm_rmx.rmx_pksent -#define RTM_VERSION4 /* Up the ante and ignore older versions */ +#if defined(_KERNEL) ! defined(SMALL_KERNEL) +/* + * Compatibility structures for version 4 messages. + * Remove them after OpenBSD 5.5. + */ +struct rt_ometrics { + u_int64_t rmx_pksent; /* packets sent using this route */ + u_int rmx_locks; /* Kernel must leave these values */ + u_int rmx_mtu;/* MTU for this path */ + u_int rmx_expire; /* lifetime for route, e.g. redirect */ + u_int rmx_refcnt; /* # references hold */ + /* some apps may still need these no longer used metrics */ + u_int rmx_hopcount; /* max hops expected */ + u_int rmx_recvpipe; /* inbound delay-bandwidth product */ + u_int rmx_sendpipe; /* outbound delay-bandwidth product */ + u_int rmx_ssthresh; /* outbound gateway buffer limit */ + u_int rmx_rtt;/* estimated round trip time */ + u_int rmx_rttvar; /* estimated rtt variance */ +}; +struct rt_omsghdr { + u_short rtm_msglen; /* to skip over non-understood messages */ + u_char rtm_version;/* future binary compatibility */ + u_char rtm_type; /* message type */ + u_short rtm_hdrlen; /* sizeof(rt_msghdr) to skip over the header */ + u_short rtm_index; /* index for associated ifp */ + u_short rtm_tableid;/* routing table id */ + u_char rtm_priority; /* routing priority */ + u_char rtm_mpls; /* MPLS additional infos */ + int rtm_addrs; /* bitmask identifying sockaddrs in msg */ + int rtm_flags; /* flags, incl. kern message, e.g. DONE */ + int rtm_fmask; /* bitmask used in RTM_CHANGE message */ + pid_t rtm_pid;/* identify sender */ + int rtm_seq;/* for sender to identify action */ + int rtm_errno; /* why failed */ + u_int rtm_inits; /* which metrics we are initializing */ + struct rt_ometrics rtm_rmx; /* metrics themselves */ +}; +#define RTM_OVERSION 4 /* Provide backward compatibility */ +#endif /* defined(_KERNEL) ! defined(SMALL_KERNEL) */ + +#define RTM_VERSION5 /* Up the ante and ignore older versions */ #define RTM_MAXSIZE2048/* Maximum size of an accepted route msg */ Index: net/rtsock.c === RCS file: /data/mirror/openbsd/cvs/src/sys/net/rtsock.c,v retrieving revision 1.129 diff -u -p -u -p -r1.129
Re: kernel route 64 bit expire time
On Tue, Oct 15, 2013 at 12:43:16AM +0200, Alexander Bluhm wrote: Convert the route expire timestamp in kernel and routing message to 64 bit. Add a small compatibility layer that allows to set routes with old user land and new kernel. You can still config addresses with old ifconfig and new kernel. I have increased the compatibility layer, route get also works in this setup. dhclient still hangs as I have do not generate old messages for interface address changes. I would like to get that in as it is. ok? The time is right. Please do this soon. Make sure that current.html has an entry warning of this. I'll cross over snapshots as quickly as possible.
bgpd vpnv4 route decision while importing prefix to rdomain
Hi! I have noticed that it seems like bgpd does not route decision if pt_entry has different RD. OpenBSD 5.2route-collection turned off.mpls-PE route-reflector advertises two prefixes with different RD and set of ATTR, both appeared in RIB-in as expected. Now, bgpd should import prefixes to rdomain by import-targets and then it should make route decision based on ATTR (in this case - lpref) BGP routing table entry for rd :10895 10.100.41.0/30Nexthop 172.16.1.2 (via 172.16.1.2) from mpls-PE (172.17.2.1)Origin incomplete, metric 0, localpref 100, weight 0, external, valid, bestLast update: 02:32:18 agoCommunities: :9004Ext. communities: rt :103231 BGP routing table entry for rd :12193 10.100.41.0/30 Nexthop 172.16.1.2 (via 172.16.1.2) from mpls-PE (172.17.2.1)Origin IGP, metric 0, localpref 120, weight 0, external, valid, bestLast update: 02:32:20 agoCommunities: :9001 :9801 :1107 :1805Ext. communities: rt :103231 But, rdomain has only first prefix in LIST (with worst lpref).If that is not a bug is there a way to change that to right way?
Re: update perl Module::Build in base
It might be worth updating the in-tree perl to the latest, version 5.18.1. This is not something I have time for myself, however. - todd
Re: update perl Module::Build in base
On Wed, Oct 30, 2013 at 08:31:58PM +0100, Ingo Schwarze wrote: -'DISTRIBUTION' = 'DAGOLDEN/Module-Build-0.39_01.tar.gz', +'DISTRIBUTION' = 'LEONT/Module-Build-0.4007.tar.gz', It's only 4.003 in 5.18, not sure if that makes a difference, but this patch would need to be ported forward if we move to newer versions of perl. https://github.com/Perl/perl5/tree/maint-5.18/cpan/Module-Build Module::Build will be deprecated as a core module in 5.20 (May 2014) and removed in 5.22 (I guess May 2015). http://www.dagolden.com/index.php/2140/paying-respect-to-modulebuild/ Post vBSDcon I have most existing patches working with 5.18.1, the only failing so far is that with threads enabled t/op/threads-dirh.t fails. (mv patches/{APPLIES,GOOD}/use_threads.patch) This test appears to point to a failure that needs fixing but I am not skilled enough to know how. https://github.com/afresh1/OpenBSD-perl Would it be preferred to plan ahead for removal and to somehow do this update in the ports tree? Other than that, the changes that I saw in that patch didn't look scary to me and I would be happy to use the updated version, three argument open seems like a good improvement. l8rZ, -- andrew - http://afresh1.com At the source of every error which is blamed on the computer, you will find at least two human errors, including the error of blaming it on the computer.
alpha pmap pool tweak
can someone with an alpha test this diff for me? if your computer still boots after you're running a kernel with it, i will consider it tested. Index: arch/alpha/alpha/pmap.c === RCS file: /cvs/src/sys/arch/alpha/alpha/pmap.c,v retrieving revision 1.63 diff -u -p -r1.63 pmap.c --- arch/alpha/alpha/pmap.c 10 Apr 2012 15:50:52 - 1.63 +++ arch/alpha/alpha/pmap.c 19 Sep 2013 07:45:12 - @@ -459,7 +459,7 @@ struct pool_allocator pmap_l1pt_allocato pmap_l1pt_alloc, pmap_l1pt_free, 0, }; -intpmap_l1pt_ctor(void *, void *, int); +void pmap_l1pt_ctor(pt_entry_t *); /* * PV table management functions. @@ -894,7 +894,6 @@ pmap_bootstrap(paddr_t ptaddr, u_int max pool_allocator_nointr); pool_init(pmap_l1pt_pool, PAGE_SIZE, 0, 0, 0, l1ptpl, pmap_l1pt_allocator); - pool_set_ctordtor(pmap_l1pt_pool, pmap_l1pt_ctor, NULL, NULL); pool_init(pmap_asn_pool, pmap_ncpuids * sizeof(u_int), 0, 0, 0, pmasnpl, pool_allocator_nointr); pool_init(pmap_asngen_pool, pmap_ncpuids * sizeof(u_long), 0, 0, 0, @@ -3438,6 +3437,7 @@ pmap_lev1map_create(pmap_t pmap, cpuid_t return (ENOMEM); } + pmap_l1pt_ctor(l1pt); pmap-pm_lev1map = l1pt; simple_unlock(pmap_growkernel_slock); @@ -3506,12 +3506,12 @@ pmap_lev1map_destroy(pmap_t pmap, cpuid_ /* * pmap_l1pt_ctor: * - * Pool cache constructor for L1 PT pages. + * Constructor for L1 PT pages. */ int -pmap_l1pt_ctor(void *arg, void *object, int flags) +pmap_l1pt_ctor(pt_entry_t *l1pt) { - pt_entry_t *l1pt = object, pte; + pt_entry_t pte; int i; /*
fd(4): replace disksort() with a bufq
this replaces the bare use of disksort with a bufq in fd. this means it will use the new system default of the nscan sorting algorithm, but that shouldnt be a noticable change. it works for me, but i would love to hear from someone with a real floppy drive still... ok? Index: fd.c === RCS file: /cvs/src/sys/dev/isa/fd.c,v retrieving revision 1.94 diff -u -p -r1.94 fd.c --- fd.c11 Jun 2013 16:42:15 - 1.94 +++ fd.c31 Oct 2013 03:05:19 - @@ -119,7 +119,8 @@ struct fd_softc { TAILQ_ENTRY(fd_softc) sc_drivechain; int sc_ops; /* I/O ops since last switch */ - struct buf sc_q;/* head of buf chain */ + struct bufq sc_bufq;/* pending I/O */ + struct buf *sc_bp; /* the current I/O */ struct timeout fd_motor_on_to; struct timeout fd_motor_off_to; struct timeout fdtimeout_to; @@ -299,6 +300,7 @@ fdattach(struct device *parent, struct d */ fd-sc_dk.dk_flags = DKF_NOLABELREAD; fd-sc_dk.dk_name = fd-sc_dev.dv_xname; + bufq_init(fd-sc_bufq, BUFQ_DEFAULT); disk_attach(fd-sc_dev, fd-sc_dk); /* Setup timeout structures */ @@ -414,11 +416,13 @@ fdstrategy(struct buf *bp) bp-b_blkno, bp-b_bcount, fd-sc_blkno, bp-b_cylinder, sz); #endif + /* Queue I/O */ + bufq_queue(fd-sc_bufq, bp); + /* Queue transfer on drive, activate drive and controller if idle. */ s = splbio(); - disksort(fd-sc_q, bp); timeout_del(fd-fd_motor_off_to); /* a good idea */ - if (!fd-sc_q.b_active) + if (fd-sc_bp == NULL) fdstart(fd); #ifdef DIAGNOSTIC else { @@ -449,7 +453,7 @@ fdstart(struct fd_softc *fd) int active = !TAILQ_EMPTY(fdc-sc_link.fdlink.sc_drives); /* Link into controller queue. */ - fd-sc_q.b_active = 1; + fd-sc_bp = bufq_dequeue(fd-sc_bufq); TAILQ_INSERT_TAIL(fdc-sc_link.fdlink.sc_drives, fd, sc_drivechain); /* If controller not already active, start it. */ @@ -464,6 +468,10 @@ fdfinish(struct fd_softc *fd, struct buf splassert(IPL_BIO); + bp-b_resid = fd-sc_bcount; + fd-sc_skip = 0; + fd-sc_bp = bufq_dequeue(fd-sc_bufq); + /* * Move this drive to the end of the queue to give others a `fair' * chance. We only force a switch if N operations are completed while @@ -473,15 +481,11 @@ fdfinish(struct fd_softc *fd, struct buf if (TAILQ_NEXT(fd, sc_drivechain) != NULL ++fd-sc_ops = 8) { fd-sc_ops = 0; TAILQ_REMOVE(fdc-sc_link.fdlink.sc_drives, fd, sc_drivechain); - if (bp-b_actf) { + if (fd-sc_bp != NULL) { TAILQ_INSERT_TAIL(fdc-sc_link.fdlink.sc_drives, fd, sc_drivechain); - } else - fd-sc_q.b_active = 0; + } } - bp-b_resid = fd-sc_bcount; - fd-sc_skip = 0; - fd-sc_q.b_actf = bp-b_actf; biodone(bp); /* turn off motor 5s from now */ @@ -661,11 +665,10 @@ loop: } fd_bsize = FD_BSIZE(fd); - bp = fd-sc_q.b_actf; + bp = fd-sc_bp; if (bp == NULL) { fd-sc_ops = 0; TAILQ_REMOVE(fdc-sc_link.fdlink.sc_drives, fd, sc_drivechain); - fd-sc_q.b_active = 0; goto loop; } @@ -927,7 +930,7 @@ fdtimeout(void *arg) #endif fdcstatus(fd-sc_dev, 0, timeout); - if (fd-sc_q.b_actf) + if (fd-sc_bp != NULL) fdc-sc_state++; else fdc-sc_state = DEVIDLE; @@ -940,7 +943,7 @@ void fdretry(struct fd_softc *fd) { struct fdc_softc *fdc = (void *)fd-sc_dev.dv_parent; - struct buf *bp = fd-sc_q.b_actf; + struct buf *bp = fd-sc_bp; if (fd-sc_opts FDOPT_NORETRY) goto fail;