RE: [PATCH] style(5): No struct typedefs
> On Fri 2023-07-14 08:12, Jason Thorpe wrote: > > > > The typedef itself buys you nothing but a few charactes less to type, > > No, that’s not correct. For a type that’s meant to be “opaque” (i.e. “users > of the interface should not have to know or > care about any of the implementation details, historical leakage be damned”), > the typedef gives you true opacity… > if you’re using “struct kmutex *” rather than “kmutex_t *” then you’re > already eating the forbidden fruit. Jason is right about this. I've had to change internal implementations in our code from "struct" to "union" at the top level. (This was because of a need to increase the level of abstraction in the implementation.) That refactor had no impact on client code. Our code uses typedef style, and whatever its merits, the style allows refactoring of the implementation, provided that you separate the API header files from the implementation (and don't disclose the implementation for use by client source code). --Terry
RE: wait(2) and SIGCHLD
David Holland wrote: >> I would say so, especially since that would mean the child's parent is > > no longer the process that forked it (which could break other use >> cases). > > That depends on how you implement detaching, but I suppose ultimately > it's important for getppid() to revert to 1 at the point the parent > exits (neither before, nor after, nor never) so some kind of linkage > needs to remain. > > Bah. > > I guess it's time to invent yet another different interface to > fork-and-really-detach. No time to experiment today, but from the descriptions it sounds as if a double fork would work, with the child exiting immediately after forking the grandchild? Kind of unpleasant, but nothing new needed? --Terry
RE: USB error checking
Robert Swindells wrote: > I posted a few weeks ago that I could reboot my Pinebook by doing: > > % cat /dev/video0 > foo.jpg > > I have now got it to drop into DDB and found that it is triggering an > assertion in sys/arch/arm/arm32/bus_dma.c:_bus_dmamap_sync(). > >KASSERTMSG(len > 0 && offset + len <= map->dm_mapsize, > "len %lu offset %lu mapsize %lu", > len, offset, map->dm_mapsize); > > with len = 0. > > I'm guessing that the video camera is returning bad USB packets. For what it's worth, a zero-length USB packet in a video stream is expected and frequent if you're doing variable-length (jpeg) compression over an isochronous stream. (The video stream is compressed, and the compressed frames are sent synchronously; so when you're done with data for a given frame, you have to send zero-length packets in each sample interval to let the host know that it's grabbed all the data.) Given how EHCI hardware works, the buffer was allocated and is non-zero in size; the actual size that came back in the descriptor is zero. I suppose that usb_transfer_complete(), which is probably not EHCI-specific, optimized the bus map call by only mapping the portion with valid data. Zero-length USB packets are a very common scenario for everything except Mass Storage, keyboards, and mice (which almost never send zero-length packets on a data pipe). The man page for bus_dmamap_sync() doesn't say that a length of zero is forbidden. Best regards, --Terry
RE: svr4, again
> Jason Thorpe wrote: While I agree that it’s not exactly difficult to maintain the a.out exec package, I do wonder if there is anyone out there actually running ancient a.out binaries. >>> >>> NetBSD 0.9 i386 a.out yes. >> >> Here, too. > > Well, then you have my sympathies, my admiration, and my curiosity all at the > same time! > > No, seriously, what ancient binaries are you running? (Ok, I admit, it's > pretty cool that it still works after all this time...) Nothing as nice as Franz Lisp. Internal little utilities for which we don’t have source handy and/or we're too lazy to rebuild. I have a (licensed) version of Unipress Emacs, but I finally gave up and rebuilt that around the 5.0 transition because of X issues; and as I'm the only user here for that, and I've finally moved on, it's only the old utilities. It's always just been cheaper (in time) to dig up the 0.9 emulation. We've been running NetBSD since 1994 or so, I think, so these kinds of things accumulate. If github had been around in 1994 they'd probably all be open source and readily buildable. But... The big issue with maintaining older tools is that they don't always recompile with new compilers; even if they actually work. People make the toolchains more and more persnickety, and it's just not worth the effort to track the compiler flavor of the week, when the problem is not that the tools are wrong, but that they were written with a more "assembly-language in C" mindset. Which is seriously out of style. --Terry
RE: svr4, again
Kamil Rytarowski wrote: >> While I agree that it’s not exactly difficult to maintain the a.out exec >> package, I do wonder if there is anyone out there actually running ancient >> a.out binaries. >> > > NetBSD 0.9 i386 a.out yes. Here, too.
RE: USB port numbering
Emmanuel Dreyfus wrote: > > That part of your change is puerly cosmetic, > > The idea was to be consistent everywhere we loop on ports. For what it's worth, the USB spec (especially 3.x) uses origin-1 port numbers. This is true from USB 1.0 in the hub commands, but starting with USB 3.0 traffic is addressed to devices using "routing strings": sequences of port-numbers; since there are a variable number of levels in the tree (based on how many hubs there are in the path), a zero means "end of string". These are used by hardware in that form. So it is probably good to use origin-1 for port numbers everywhere. Using origin-0 in some places and origin-1 in others is a maintenance problem. I think you're right to want consistency. Best regards --Terry
RE: Reboot resistant USB bug
Emmanuel Dreyfus wrote: > I did not post the whole patch for the sake of clarity, but it seems it was a > mistake. Please find it below. > > The substituted values are chosen based on vendorId/producId obtained earlier > from the device descriptor (which fortunately does not get corrupted). If one > swaps the device, I understand the struct usbd_device on which we operate is not > the same anymore, and productId/vendorId are up to date. Apologies for misunderstanding. If you are able to get the device descriptor, then this ought to work. In Windows, since they match only on vid/pid/rev, for a simple device, they can put this fix in the device driver. That might also be an approach to take in NetBSD. On multi-function devices, Windows will insist on reading and examining the config descriptor in the multi-function "bus" driver, and bad things will happen if data is not consistent. So this is most likely to be a problem with relatively simple devices. FWIW, this change increases the analysis surface for the USB stack, since a reviewer has to understand the possible descriptor substitutions, and the subsitutions are not with the rest of the code of the device. Best regards, --Terry
RE: Reboot resistant USB bug
Your code looks like a change to the core USB stack. You're using a get-descriptor failure to trigger a stuff. If I'm right about where the change is located, at that layer, the code has no idea if that failure might be expected. You're just substituting a value. You don't actually know that the device is the device you think it is, because you don't know if someone put you to sleep, and swapped devices on that port, and rebooted. Your fix is fine for a private fix, but if I understand it correctly it won't do the right thing for the general case. --Terry -Original Message- From: tech-kern-ow...@netbsd.org On Behalf Of Emmanuel Dreyfus Sent: Tuesday, October 16, 2018 19:19 To: Terry Moore Cc: tech-kern@netbsd.org Subject: Re: Reboot resistant USB bug Terry Moore wrote: > Also, some descriptor-gets will normally fail, and it's important to pass > the failure to the caller. So I believe that your fix will have unforeseen > side-effects. Well, here the chip documentation states the USB descriptors are immutable. I used the values from that documentation to fake them once they get corrupted. How can this go wrong? -- Emmanuel Dreyfus http://hcpnet.free.fr/pubz m...@netbsd.org
RE: Reboot resistant USB bug
Speaking as a USB host-stack person: it's a bad idea to assume that a device has not changed after a reboot of the system. Also, some descriptor-gets will normally fail, and it's important to pass the failure to the caller. So I believe that your fix will have unforeseen side-effects. It is unfortunately true that the accepted test plan for many USB devices is: * plug into Windows * does it work? * ship it This means that host stacks have to emulate the Windows enumeration system precisely in order to maximize compatibility. Does this device work properly under Windows? If so, you can perhaps ask someone to get you a bus trace of the Windows enumeration and compare to NetBSD. --Terry -Original Message- From: tech-kern-ow...@netbsd.org On Behalf Of Emmanuel Dreyfus Sent: Tuesday, October 16, 2018 08:27 To: Emmanuel Dreyfus Cc: tech-kern@netbsd.org Subject: Re: Reboot resistant USB bug On Thu, Oct 11, 2018 at 02:11:22PM +, Emmanuel Dreyfus wrote: > On both netbsd-8 and -current, I have a problem with USB devices that > get stuck in a non-functionning state even after a reboot. I investigated a lot: in my example, the pn533 chip seems to corrupts its USB config, interface and endpoint descriptors. They contain garbage, and on reboot the kernel cannot figure enough about the device, and disable the USB port. But if I detect the condition in usbd_get_desc() and inject fake descriptors (see below), the device is correctly attached on reboot, and it works again. Is it an acceptable workaround? usbd_status usbd_get_desc(struct usbd_device *dev, int type, int index, int len, void *desc) { usb_device_request_t req; usbd_status err; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); DPRINTFN(3,"type=%jd, index=%jd, len=%jd", type, index, len, 0); req.bmRequestType = UT_READ_DEVICE; req.bRequest = UR_GET_DESCRIPTOR; USETW2(req.wValue, type, index); USETW(req.wIndex, 0); USETW(req.wLength, len); err = usbd_do_request(dev, , desc); /* * Attempt to fake the descriptor if it fails sanity check */ if (err == USBD_NORMAL_COMPLETION) { usb_descriptor_t *d = desc; if (d->bDescriptorType != type || d->bLength > len) err = usbd_get_desc_fake(dev, type, index, len, desc); } return err; } -- Emmanuel Dreyfus m...@netbsd.org
RE: ddb input via IPMI virtual console
>> The real keyboards are PS/2 and I can't change that because it runs >> on a wire physically passing a /real/ firewall, [...] > >(a) Is it possible to run USB over the same conductors used by the PS/2 >cable? (This is a real question; I don't know enough about layer 1 of >either to answer it.) Great question. The answer is "yes, if you're desperate". Keyboards are low-speed or full-speed USB devices, and the signaling is relatively non-critical -- especially if you find a low-speed keyboard. However: >(b) There exist devices that adapt PS/2 to USB in the >PS/2-keyboard-to-USB-host direction. Since the problem is that the real keyboards are PS/2, the adapters sound perfect. https://www.newegg.com/Mouse-Keyboard-PS2-Adapters/SubCategory/ID-3024 US$ 6 pretty reasonable. Put it in the machine room, use the existing PS/2 keyboards, and... isn't the problem solved? If you need USB as well from another source, use a hub (in the machine room). But I confess I'm not clear about that part of what you're trying to do. --Terry
RE: meltdown
> I think you are confusing spectre and meltdown. Yes, my apologies. --Tery
RE: how to tell if a process is 64-bit
Hi, > In a cross-platform process utility tool the question came up how to decide if a process is 64-bit. > > https://github.com/giampaolo/psutil/issues/1102 > > What's the best answer for NetBSD? If I understand correctly, you want psutil-based scripts -- which seem to be written in Python -- to be able to ask "is-64" about other processes? I suppose you are therefore interested in knowing the base ISA of a given process from outside the process? (As others have mentioned, you might instead, or additionally, be interested in the emulation that's in use.) Are you looking for the system calls, or the python equivalents? Can you clarify? Best regards, --Terry
RE: USB device [was "USB slave"]
>> > Is it possible to use a USB port as a USB slave? I would like to >> > make it act as a keyboard to output some data to another machine. > Isn't there already a slave side USB driver for emulated ethernet for StrongARM/PXA devices ? Hi all, As the lurking member of USB-IF, and someone who has been using NetBSD since before there was a USB, and who uses NetBSD daily as a development system for USB system software, I think it's great that we're going to add USB device support to NetBSD. However, please, please, please: let us follow the USB standard nomenclature. USB does not use the terms "master" and "slave". These terms are for other technologies. The USB community uses the terms "host" and "device". Can we please follow industry practice? Even if other POSIX-like systems use other terms, we would be much better off following USB terminology. That way, the terms will map closely to the specifications, and old-timers like me will be able to follow the discussions more easily Thanks! --Terry
RE: ugen vs interfaces
> So when I open /dev/ugen1.02 and read, it uses 0x82, but if I write, it > uses 0x02? Or at least it should? Because there is no /dev/ugen1.130 > or any such - nor does the minor-number cracking code in the driver > show anything of the sort. That is what I would guess. > Ooo. So an interface is not actually visible on the wire, except in > the form of the device saying "here, put these fragments together and > they collectively form a conceptual thing" when queried? Things make a > bit more sense to me now. That is exactly true. Interfaces can be discovered, but in the low-level protocol packets are addressed with a 7-bit device address and a 4-bit endpoint address (with the further understanding that the endpoint address for OUT transactions is independent of the address for IN transactions). Even when sending control messages to interfaces, a bus analyzer sees a control transaction to endpoint 0, and a a SETUP packet. The packet (in byte 0) indicates "this is for an interface" and (in byte 3, if memory serves) further indicates "this is for interface N" -- and 4 of the other 6 bytes can be used to pass additional protocol-specific information. (A further payload can be sent, or received, but not both.) The control transactions are basically an RPC, where you can write L bytes and get 1 bit of status; or read (up to) L bytes or get one bit of error status. So the device software does muxing. Best regards, --Terry
RE: ugen vs interfaces
[apologies in advance, I'm using Outlook which really is annoying for plain text/list responses. Let me know if I should have hard-wrapped the line-endings, I forget the convention.] > So the "intf 1 ep 0" endpoint is actually the same thing as the "intf 2 > ep 1" endpoint, because they're both address 2, even though one is > UE_DIR_IN and the other is UE_DIR_OUT? Or am I still confused? The bEndpointAddress 0x82 is not the same as 0x02 -- at least to the hardware on your device. (The sign bit counts here. IN endpoint 0x02 has the same bottom 4 bits of address as OUT endpoint 0x02, but because the direction is different, they're different endpoints. > What about the "intf 0 ep 0" endpoint, which is address 1, UE_DIR_IN, > UE_INTERRUPT, and the "intf 1 ep 1" endpoint, which is UE_DIR_OUT and > UE_BULK - but also address 1? Same thing. Because the direction is different, the hardware is not confused, and the collision is coincidental. > Or are the bEndpointAddress values here not the addresses you're > talking about? Definitely what I'm talking about. > Perhaps it would also help to ask "what's an interface"? They seem to > be at the heart of my confusion here An interface is primarily an abstraction of interest to software on the host. An 'interface' represents: 1) a collection of endpoints that represent a logical function on a multi-function device. 2) (in conjunction with alternate interface settings) a way of managing bandwidth allocation for isochronous and interrupt data flows. 3) something that can be addressed with control transactions and SETUP packets (independently of the device or of endpoints). Sometimes a logical function needs to do #2 independently for multiple data flows. For example, an audio device may have separate flows for the speaker and the mic. In fact, an audio function often has three interface descriptors: one for control, one for the speaker and one for the mic. The control interface might not have any endpoints, but audio class uses #3 to send messages to its function. To make matters even more complicated, you often see an audio function (with multiple interfaces) combined with a HID function (with one interface. Modern USB uses a special descriptor, the INTERFACE ASSOCIATION DECRIPTOR, to indicate that several interfaces are part of the same logical function. More than you wanted to know, I'm sure. Back to your problem: it seems likely that ugen binds to the entire device. In this case, I would expect that you would use the endpoint *addresses* to send traffic. You would mask off the direction bit, and for reads, it will access address 0x80 | ; for writes, it will send to address . If ugen can't deal with the fact that endpoint addresses IN and OUT are not logically related to each other, then it needs an update Best regards, --Terry
RE: ugen vs interfaces
The following might or might not be helpful. Endpoint *addresses* are a flat space in USB. Endpoint *indices* within interface are almost never used. If your device doesn't have multiple configuration or multiple alternate settings, the endpoint address is enough. Endpoint (index) 3 of interface 5 is only a config time concept; I/O is always sent to endpoint *address* whatever. If your device has multiple configs and/or alternate settings, then you have to select the config and setting. In this context, the meaning of endpoint address x changes (as determined by the governing active config or alternate setting -- you look at the endpoint descriptor under the selected config/alternate setting to find out the meaning). Best regards, --Terry -Original Message- From: tech-kern-ow...@netbsd.org [mailto:tech-kern-ow...@netbsd.org] On Behalf Of Mouse Sent: Tuesday, November 15, 2016 15:19 To: tech-kern@netbsd.org Subject: ugen vs interfaces I'm trying to use ugen - on 5.2, but a look at cvsweb (ugen.4 and ugen.c) makes me think current is identical in these regards. I've forced the device of interest to configure as ugen ("flags 1") and my code can find it (bus 3 device 3, at the moment, for example). The example code I'm working from was designed (of course :-þ) for Linux, and seems to use interface 2. But I can't see how to tell NetBSD I want to use interface 2. I can _find_ interface 2, by walking interfaces and endpoints on the control endpoint. But I can't figure out how to tell the kernel I want to do bulk I/O on endpoint 3 of interface 2. The ugen device name specifies the bus and device (via the ugen instance, in the high bits) and the endpoint number (in the low four bits). But I can't see anywhere I can set the interface number. I can't see any way to set anything on the control endpoint so that opening the /dev/ugen* devices will come up using the interface I want and I can't see anything I can do with the endpoint file descriptor once opened that will cause it to switch to using the interface I want. Surely I'm just missing something...but what? I can, of course, give more details if they'd help. But I suspect there's just something simple I'm not getting /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
RE: In-kernel process exit hooks?
Will the hang occur if make dies due to a signal (control-C, or kill -9, for example)? --Terry > -Original Message- > From: tech-kern-ow...@netbsd.org [mailto:tech-kern-ow...@netbsd.org] On > Behalf Of Paul Goyette > Sent: Thursday, January 7, 2016 17:00 > To: Taylor R Campbell> Cc: tech-kern@netbsd.org > Subject: Re: In-kernel process exit hooks? > > On Fri, 8 Jan 2016, Paul Goyette wrote: > > > The saga continues! :) > > > > > > > > Next, I'm going to have a look at fd_getfile2()/fclose() and see if > > that is a viable approach. > > Hmmm. The comments in kern/kern_descrip.c for fd_getfile2() require that > the process is not allowed to fork or exit "across this call" > (which I assume means "until the reference to the struct file is released"). > > I'm not sure how to prevent this. I could probably re-use the exithook > mechanism from the previous approach to handle the exit case, but how to > prevent fork() is another beast entirely (I think). And to make things > worse, the example code in the filemon(4) man page explicitly calls fork(). > > I'm quickly running out of ideas here... I'm strongly leaning towards > leaving the code alone, and more clearly documenting the conditions under > which the hang occurs (ie, closure of the activity-log fd prior to > disassociated the activity-log from the /dev/filemon fd, whether the close > is done explicitly or as part of the sequential close that occurs at process > exit). > > Someone (Martin@, I think) earlier suggested modifying things to use > cv_timedwait() in fd_close(), and modifying fd_free() to retry. This might > help in the process exit scenario, but doesn't address the case where the > application process explicitly closes the file with the extra reference. > > It might also be possible to modify fd_close() to have a filemon-specific > close routine, similar to what is currently being done for knote_fdclose(). > But this seems rather heavy-handed for something that has such a limited > use-case as filemon(4). > > The only other approach I can think of is to modify filemon(4) so it does > not directly write any data to the activity log. Rather than having the > application provide a log fd (on which the extra reference needs to be > taken), the application would read(2) from the filemon fd and handle the > "logging" itself. This would mean two additional trips across the > kernel/userland boundary for every event, which feels like a rather costly > approach. It would also mean modifying make(1) (the only "production" use- > case for filemon(4)). > > > Any other suggestions would be appreciated. > > > +--+--++ > | Paul Goyette | PGP Key fingerprint: | E-mail addresses: | > | (Retired)| FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com | > | Kernel Developer | 0786 F758 55DE 53BA 7731 | pgoyette at netbsd.org | > +--+--++
RE: Potential problem with reading data from usb devices with ugen(4)
Not only legitimate, but required, depending on the class protocol. Best regards, --Terry > -Original Message- > From: tech-kern-ow...@netbsd.org [mailto:tech-kern-ow...@netbsd.org] On > Behalf Of Greg Troxel > Sent: Wednesday, December 30, 2015 17:36 > To: Brian Buhrow> Cc: Nick Hudson ; Nick Hudson ; > tech-kern@NetBSD.org > Subject: Re: Potential problem with reading data from usb devices with > ugen(4) > > > Brian Buhrow writes: > > > To answer your question about whether there is a standard for > > generating these packets, it seems there is not. Linux expects you to > > use an ioctl() to generate the packet while FreeBSD expects you to > > send a write request with 0 bytes, as we do with the ugen(4) changes I'm > making. > > I meant: in the USB specification, is it legitimate to do zero-length > transfer?
RE: Brainy: UAF in iscsi_ioctl.c
> > Well, we love Brainy and we always give it credit (or at least try to)! > > > > christos > > Yep! > > I'm just wondering when Max packages up the Brainy tool and starts > getting customers to actually pay for it! It really is one very > excellent tool. +1
RE: change MSI/MSI-X APIs
-Original Message- From: tech-kern-ow...@netbsd.org [mailto:tech-kern-ow...@netbsd.org] On Behalf Of Kengo NAKAHARA Sent: Sunday, May 17, 2015 23:58 To: tech-kern@netbsd.org; t...@mcci.com Cc: chris...@astron.com Subject: Re: change MSI/MSI-X APIs I'm sure there are even better ways to handle this variation; just making a concrete example of how it might be done. What do you think about below pci_intr_alloc() API? http://mail-index.netbsd.org/tech-kern/2015/05/18/msg018725.html I think this API simplify for many device drivers to use, however I am unsure this API meets your pointing out. Could you comment? Hi Nakahara-san, I think you and Christos are converging on something that will be quite suitable. Too many cooks spoil the broth, as the cliché goes, so I'll stay out of the kitchen. Best regards, --Terry
RE: change MSI/MSI-X APIs
From: tech-kern-ow...@netbsd.org [mailto:tech-kern-ow...@netbsd.org] On Behalf Of Kengo NAKAHARA Hi On 2015/05/11 23:18, Christos Zoulas wrote: Can't we have a: int pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ih); for the drivers that have only one interrupt, and: int pci_intr_vector_map(struct pci_attach_args *pa, pci_intr_handle_t **ihp, size_t *nih); for drivers that can handle more than one? Because some device drivers must select INTx, MSI, or MSI-X depending on using devices; e.g. some devices have errata about MSI-X, so the device driver cannot use MSI-X even if the devices have MSI-X capability. In addition, some other the device drivers should use MSI-X and INTx only since some devices have errata about MSI. In a similar way, other device drivers should use MSI-X and MSI only. These selection logic codes can be done only in the device drivers codes, therefore it is required for the device drivers to be able to select interrupt types by allocation APIs. I completely understand that *some* devices have this problem. But many devices do not. It seems that the current API penalizes drivers for devices that are done correctly. Would it not make more sense to make drivers more complex only for devices that require the complexity? One way to handle this without multiplying APIs unnecessarily is to have a flags argument to pci_intr_map() and pci_intr_vector_map() that allows the driver to restrict the mapping. The driver for the broken case would have to fill out more of the interrupt structure, but the simple driver could be simple. I'm sure there are even better ways to handle this variation; just making a concrete example of how it might be done. Best regards, --Terry
RE: FW: ixg(4) performances
-Original Message- From: Hisashi T Fujinaka [mailto:ht...@twofifty.com] Sent: Sunday, August 31, 2014 12:39 To: Terry Moore Cc: tech-kern@netbsd.org Subject: RE: FW: ixg(4) performances I may be wrong in the transactions/transfers. However, I think you're reading the page incorrectly. The signalling rate is the physical speed of the link. On top of that is the 8/10 encoding (the Ethernet controller we're talking about is only Gen 2), the framing, etc, and the spec discusses the data rate in GT/s. Gb/s means nothing. Hi, I see what the dispute is. The PCIe 3.0 spec *nowhere* uses transfers in the sense of UNIT INTERVALs (it uses UNIT INTERVAL). The word transfer is not used in that way in the spec. Transfer is used, mostly in the sense of a larger message. It's not in the glossary, etc. However, you are absolutely right, many places in the industry (Intel, Wikipedia, etc.) refer to 2.5GT/s to mean 2.5G Unit Intervals/Second; and it's common enough that it's the de-facto standard terminology. I only deal with the spec, and don't pay that much attention to the ancillary material. We still disagree about something: GT/s does mean *something* in terms of the raw throughput of the link. It tells the absolute upper limit of the channel (ignoring protocol overhead). If the upper limit is too low, you can stop worrying about fine points. If you're only trying to push 10% (for example) and you're not getting it, you look for protocol problems. At 50%, you say hmm, we could be hitting the channel capacity. I think we were violently agreeing, because the technical content of what I was writing was (modulo possible typos) identical to 2.5GT/s. 2.5GT/s is (after 8/10 encoding) a max raw data rate of 250e6 bytes/sec, and when you go through things and account for overhead, it's very possible that 8 lanes (max 2e9 bytes/sec) of gen1 won't be fast enough for 10G Eth. Best regards, --Terry
RE: FW: ixg(4) performances
From Emmanuel Dreyfus You are right; # pcictl /dev/pci5 read -d 0 -f 1 0xa8 00092810 # pcictl /dev/pci5 write -d 0 -f 1 0xa8 0x00094810 # pcictl /dev/pci5 read -d 0 -f 1 0xa8 4810 That's reassuring. The dump confirms that we're looking at the right registers, thank you. As I read the spec, 0x4810 in the Device Control Register means: Max_Read_Request_Size: 100b - 4096 bytes Enable_No_Snoop: 1 Max_Payload_Size: 000b -- 128 bytes Enable_Relaxed_Ordering: 1 All other options turned off. I think you should try: Max_Read_Request_Size: 100b - 4096 bytes Enable_No_Snoop: 1 Max_Payload_Size: 100b -- 4096 bytes Enable_Relaxed_Ordering: 1 This would give 0x4890 as the value, not 0x4810. It's odd that the BIOS set the max_payload_size to 000b. It's possible that this indicates that the root complex has some limitations. Or it could be a buggy or excessively conservative BIOS. (It's safer to program Add-In boards conservatively -- fewer support calls due to dead systems. Or something like that.) So you may have to experiment. This would explain that you saw 2.5 GB/sec before, and 2.7 GB/sec after -- you increased the max *read* size, but not the max *write* size. Increasing from 2048 to 4096 would improve read throughput but not enormously. Depends, of course, on your benchmark. --Terry
RE: FW: ixg(4) performances
-Original Message- From: Hisashi T Fujinaka [mailto:ht...@twofifty.com] Sent: Saturday, August 30, 2014 21:29 To: Terry Moore Cc: tech-kern@netbsd.org Subject: Re: FW: ixg(4) performances Doesn't anyone read my posts or, more important, the PCIe spec? 2.5 Giga TRANSFERS per second. I'm not sure I understand what you're saying. From the PCIe space, page 40: Signaling rate - Once initialized, each Link must only operate at one of the supported signaling levels. For the first generation of PCI Express technology, there is only one signaling rate defined, which provides an effective 2.5 Gigabits/second/Lane/direction of raw bandwidth. The second generation provides an effective 5.0 Gigabits/second/Lane/direction of raw bandwidth. The third generation provides an effective 8.0 Gigabits/second/Lane/direction of 10 raw bandwidth. The data rate is expected to increase with technology advances in the future. This is not 2.5G Transfers per second. PCIe talks about transactions rather than transfers; one transaction requires either 12 bytes (for 32-bit systems) or 16 bytes (for 64-bit systems) of overhead at the transaction layer, plus 7 bytes at the link layer. The maximum number of transactions per second paradoxically transfers the fewest number of bytes; a 4K write takes 16+4096+5+2 byte times, and so only about 60,000 such transactions are possible per second (moving about 248,000,000 bytes). [Real systems don't see this, quite -- Wikipedia claims, for example 95% efficiency is typical for storage controllers.] A 4-byte write takes 16+4+5+2 byte times, and so roughly 9 million transactions are possible per second, but those 9 million transactions can only move 36 million bytes. Multiple lanes scale things fairly linearly. But there has to be one byte per lane; a x8 configuration says that physical transfers are padded so that each the 4-byte write (which takes 27 bytes on the bus) will have to take 32 bytes. Instead of getting 72 million transactions per second, you get 62.5 million transactions/second, so it doesn't scale as nicely. Reads are harder to analyze, because they depend on the speed and design of both ends of the link. The reader sends a read request packet, and the read-responder (some time later) sends back the response. As far as I can see, even at gen3 with lots of lanes, PCIe doesn't scale to 2.5 G transfers per second. Best regards, --Terry
FW: ixg(4) performances
Forgot to cc the list. -Original Message- From: Terry Moore [mailto:t...@mcci.com] Sent: Friday, August 29, 2014 15:13 To: 'Emmanuel Dreyfus' Subject: RE: ixg(4) performances But it's running at gen1. I strongly suspect that the benchmark case was gen2 (since the ixg is capable of it). gen1 vs gen2 is 2.5 Gb.s vs 5 Gb/s? Yes. Actually, 2.5Gbps is symbol rate -- it's 8/10 encoded, so one lane is really 2Gbps. So 8 lanes is 16Gbps which *should* be enough, but... there's overhead and a variety of sources of wastage. I just saw today a slide that says that 8 lanes gen 1 is just barely enough for 10Gb Eth (http://www.eetimes.com/document.asp?doc_id=1323695page_number=4). It's possible that the benchmark system was using 8 lanes of Gen2. Another possibility: earlier you wrote: No reference to MMRBC in this document, but I understand Max Read Request Size is the same thing. Page 765 tells us about register A8, bits 12-14 that should be set to 100. pcictl /dev/pci5 read -d 0 -f 1 0x18 tells me the value 0x00092810 I tried this command: pcictl /dev/pci5 write -d 0 -f 1 0x18 0x00094810 In the PCIe spec, this is controlled via the Device Control register which is a 16-bit value. You want to set *two* fields, to different values. 0x18 looks like the wrong offset. The PCIe spec says offset 0x08, but that's relative to the base of the capability structure, the offset of which is in the low byte of the dword at 0x34. I am running NetBSD 5; my pcictl doesn't support write as one of its options, but I'd expect that to be relative to the base of the function config space, and *that's not the device capabilities register*. It's a read/write register, which is one of the Base Address Registers. In any case, in the Device Control Register, bits 7:5 are the max payload size *for writes* by the igx to the system. These must be set to 101b for 4K max payload size. Similarly, bits 14:12 are the max read request size. These must also be set to 101b for 4K max read request. Since you did a dword read, the extra 0x9 is the device status register. This makes me suspicious as the device status register is claiming that you have unsupported request detected) [bit 3] and correctable error detected [bit 0]. Further, this register is RW1C for all these bits -- so when you write 94810, it should have cleared the 9 (so a subsequent read should have returned 4810). Please check. Might be good to post a pcictl dump of your device, just to expose all the details. Is the ixg in an expansion slot or integrated onto the main board? In a slot. Check the manual on the main board and find out whether other slots have 8 lanes of Gen2. If so, move the board. Best regards, --Terry
RE: ixg(4) performances
-Original Message- From: tech-kern-ow...@netbsd.org [mailto:tech-kern-ow...@netbsd.org] On Behalf Of Emmanuel Dreyfus Sent: Thursday, August 28, 2014 23:55 To: Terry Moore; 'Christos Zoulas' Cc: tech-kern@netbsd.org Subject: Re: ixg(4) performances Terry Moore t...@mcci.com wrote: There are several possibilities, all revolving about differences between the blog poster's base system and yorus. Do I have a way to investigate for appropriate PCI setup? Here is what dmesg says about it: pci0 at mainbus0 bus 0: configuration mode 1 pci0: i/o space, memory space enabled, rd/line, rd/mult, wr/inv ok ppb4 at pci0 dev 14 function 0: vendor 0x10de product 0x005d (rev. 0xa3) ppb4: PCI Express 1.0 Root Port of PCI-E Root Complex pci5 at ppb4 bus 5 pci5: i/o space, memory space enabled, rd/line, wr/inv ok ixg1 at pci5 dev 0 function 1: Intel(R) PRO/10GbE PCI-Express Network Driver, Version - 2.3.10 I don't do PCIe on NetBSD -- these days we use it exclusively as VM guests --, so I don't know what tools are available. Normally when doing this kind of thing I poke around with a debugger or equivalent of pcictl. The dmesg output tells us that your ixg is directly connected to an Nvdia root complex. So there are no bridges, but this might be a relevant difference to the benchmark system. It's more common to be connected to an Intel southbridge chip of some kind. Next step would be to check the documentation on, and the configuration of, the root complex -- it must also be configured for 4K read ahead (because the read will launch from the ixg, will be buffered in the root complex, forwarded to the memory controller, and then the answers will come back. (PCIe is very fast at the bit transfer level, but pretty slow in terms of read transfers per second. Read transfer latency is on the order of 2.5 microseconds / operation. This is why 4K transfers are so important in this application.) Anyway, there are multiple vendors involved (Intel, Nvidia, your BIOS maker, because the BIOS is responsible for setting things like the read size to the maximum across the bus -- I'm speaking loosely, but basically config software has to set things up because the individual devices don't have enough knowledge). So generally that may explain things. Still, you should check whether you have the right number of the right generation of PCIe lanes connected to the ixg. If you look at the manual, normally there's an obscure register that tells you how many lanes are connected, and what generation. On the motherboards we use, each slot is different, and it's not always obvious how the slots differ. Rather than depending on documentation and the good intentions of the motherboard developers, I always feel better looking at what the problem chip in question thinks about number of lanes and speeds. Hope this helps, --Terry
RE: ixg(4) performances
On Friday, August 29, 2014 11:51, Emmanuel Dreyfus wrote: On Fri, Aug 29, 2014 at 08:48:51AM -0400, Terry Moore wrote: Still, you should check whether you have the right number of the right generation of PCIe lanes connected to the ixg. I found this, but the result does not make sense: negociated max ... Link Capabilities Ragister (0xAC): 0x00027482 bits 3:0 Supprted Link speed: 0010 = 5 GbE and 2.5 GbE speed supported bits 9:4 Max link width: 001000 = x4 bits 14:12 L0s exit lattency: 101 = 1 µs - 2 µs bits 17:15 L1 Exit lattency: 011 = 4 µs - 8 µs Link Status Register (0xB2): 0x1081 bits 3:0 Current Link speed: 0001 = 2.5 GbE PCIe link bits 9:4 Negociated link width: 001000 = x8 I think there's a typo in the docs. In the PCIe spec, it says (for Link Capabilities Register, table 7-15): 001000b is x8. But it's running at gen1. I strongly suspect that the benchmark case was gen2 (since the ixg is capable of it). Is the ixg in an expansion slot or integrated onto the main board? --Terry
RE: ixg(4) performances
Or the performance are constrained by something unrelated. In the blog post cited above, the poster acheived more than 5 Gb/s before touching MMRBC, while I am stuck at 2,7 GB/s. Any new idea welcome. The blog post refers to PCI-X, I'm more familiar with PCIe, but the concepts are similar. There are several possibilities, all revolving about differences between the blog poster's base system and yorus. 1) the test case is using a platform that has better PCI performance (in the PCIe world this could be: Gen3 versus Gen2 support in the slot being used; more lanes in the slot being used) 2) the test case has a root complex with a PCI controller with better performance than the one in your system; 3) the test case system has a different PCI configuration, in particular different bridging. For example, a PCI bridge or switch on your platform can change basic capabilities compared to the reference. 4) related to 3: one of the bridges on your system (between ixg and root complex) is not configured for 4K reads, and so the setting on the ixg board won't help [whereas this wasn't the case on the blog system]. 5) related to 4: one of the bridges in your system (between ixg and root complex) is not capable of 4K reads... (see 4). And of course you have to consider: 6) the writer has something else different than you have, for example silicon rev, BIOS, PCI-X where you have PCIe, etc. 7) the problem is completely unrelated to PCIe. You're in a tough situation, experimentally, because you can't take a working (5 Gbps) system and directly compare to the non-working (2.7 Gbps) situation. --Terry
RE: [patch] changing lua_Number to int64_t
From: Marc Balmer [mailto:m...@msys.ch] It's not *much* less safe than compiling and executing a string in the kernel. The only additional attack surfaces are that you can write things that the compiler wouldn't write. This can (1) cause a crash at load time, or it can (2) cause surprising behavior later. The problem is that malicious bytecode in 5.1 is possible. That is why there is a guad against loading bytecode. Malicious in what sense? Is this a type-1 problem or a type-2 problem? Or something else that I've not considered? --Terry
RE: [patch] safety of Lua byte code
Am 17.11.13 22:03, schrieb Terry Moore: From: Marc Balmer [mailto:m...@msys.ch] It's not *much* less safe than compiling and executing a string in the kernel. The only additional attack surfaces are that you can write things that the compiler wouldn't write. This can (1) cause a crash at load time, or it can (2) cause surprising behavior later. The problem is that malicious bytecode in 5.1 is possible. That is why there is a guad against loading bytecode. Malicious in what sense? Is this a type-1 problem or a type-2 problem? Or something else that I've not considered? See Peter Cawleys talk he gave during LWS 2011 in Frick. Mitigating the danger of malicious bytecode So we're discussing what I called a type-2 problem, escaping the sandbox. Really, however, if you load any code of any complexity into any VM, you are at risk -- no matter how it the code is presented (byte code or source). If you are loading code you don't know into a Turning-complete VM that's running in the kernel, you are making a very strong assumption (and one that seems, based on experience in the software industry to be unwarranted) about the correctness of the compiler, run-time system, etc. I am not referring to Lua in particular; the code is pretty good. I'm referring instead to the general complexity of the VM environment. I personally would never run untrusted code of any kind in the kernel, whether provided in source form or binary form, whether sandboxed or not, unless the VM is very limited (along the lines of the BPF VM). This isn't to say that Lua is not useful in the kernel. It is, however, to say that I'd be very reluctant to let an adversary have carte blanche to inject Lua code, in source or binary form, into the kernel. (This goes for *any* language, C, Python, binary. Injecting Lua code into your kernel is like doing an insmod -- you had better be asserting that you trust the code *completely*. In fact, the use case of a serial protocol coded in Lua is exactly an insmod-like application.) Nobody would seriously claim, I think, that one can algorithmically determine whether a given fragment of Lua *source* code is malicious. Yes, Lua byte codes can be malicious in additional ways, but I think worrying about this misleads us about the nature of the problem. If you're worrying about the safety of the compiled code in this sense, then you should really be worrying about the safety of having the compiler in the kernel at all. I think that the paper you refer to is more motivated by use cases such as running Lua in a web browser a-la Java, or in a game WoW, where the code is injected into a VM without any real authentication. Best regards, --Terry
RE: [patch] changing lua_Number to int64_t
I believe that if you want the Lua scripts to be portable across NetBSD deployments, you should choose a well-known fixed width. Watch out, by the way, for compiled scripts; I have not checked Lua 5.x, but you may find if not careful that the compiled binary is not loadable on machines with different choices for LP64, ILP32, etc. This is somewhat independent of the choice of lua_Number mapping. --Terry -Original Message- From: tech-kern-ow...@netbsd.org [mailto:tech-kern-ow...@netbsd.org] On Behalf Of Lourival Vieira Neto Sent: Saturday, November 16, 2013 22:36 To: Christos Zoulas Cc: tech-kern@netbsd.org Subject: Re: [patch] changing lua_Number to int64_t On Sat, Nov 16, 2013 at 10:44 PM, Christos Zoulas chris...@zoulas.com wrote: On Nov 16, 9:30pm, lourival.n...@gmail.com (Lourival Vieira Neto) wrote: -- Subject: Re: [patch] changing lua_Number to int64_t | On Sat, Nov 16, 2013 at 8:52 PM, Christos Zoulas chris...@astron.com wrote: | In article 52872b0c.5080...@msys.ch, Marc Balmer m...@msys.ch wrote: | Changing the number type to int64_t is certainly a good idea. Two | questions, however: | | Why not intmax_t? | | My only argument is that int64_t has a well-defined width and, AFAIK, | intmax_t could vary. But I have no strong feelings about this. Do you | think intmax_t would be better? Bigger is better. And you can use %jd to print which is a big win. I agree that bigger is better and %jd is much better then % PRI/SCN. But don't you think that to know the exact width is even better? Regards, -- Lourival Vieira Neto
RE: [patch] changing lua_Number to int64_t
From: Lourival Vieira Neto [mailto:lourival.n...@gmail.com] Watch out, by the way, for compiled scripts; I have not checked Lua 5.x, but you may find if not careful that the compiled binary is not loadable on machines with different choices for LP64, ILP32, etc. This is somewhat independent of the choice of lua_Number mapping. Yes, Lua bytecode isn't portable in fact. BTW, loading Lua bytecode is not recommended by Lua team. It isn't safe. It's not *much* less safe than compiling and executing a string in the kernel. The only additional attack surfaces are that you can write things that the compiler wouldn't write. This can (1) cause a crash at load time, or it can (2) cause surprising behavior later. I suspect that anyone who would want to allow Lua in the kernel would be somewhat indifferent to type-2 safety issues. If you don't trust the input string, you had better not give it to the kernel (whether or not it's compiled). Type-1 safety issues ought to be fixed, as careful examination of the input data only slows down the load process -- it has no run-time effects. Given that Lua byte codes can be translated into C arrays and then loaded via the API, portability issues can creep in through the back door. Best regards, --Terry
RE: pulse-per-second API status
Hi all, I do USB for a living. USB is not a very good way to do PPS synchronization if you're looking for usec resolution -- there are huge and unpredictable delays that can be introduced from a number of sources. Some of the sources are inherent and some are due to system issues. Sources of variation: *) the USB com port may be using an interrupt pipe to report changes in the handshaking lines. Depending on the vendor, there may be variation in the requested frequency of interrupt polling. On high-speed and superspeed devices, USB polling may occur as quickly as every 125us; on full and low-speed devices, the polling interval drops to 1ms max. However, when you get polled within a given 125us or 1ms window will vary based on other devices on the bus. You cannot control this, in general, unless you dedicate a host controller and only plug one device into the bus. Furthermore, even on an unloaded bus, your sampling (polling) frequency will be slaved to the clock of the USB host controller, with additional jitter introduced by the clock of the USB device controller. *) the USB com port may be using a bulk pipe to report changes in the handshaking lines. On a bus with multiple devices, the polling for any particular endpoint will have gaps that are not predictable. Even on an unloaded bus, there are gaps close to end of each frame or microframe during which polls will not occur. *) after the USB I/O operation completes at the hardware, there is unpredictable latency introduced by the USB subsystem. This latency often applies even if you have a dedicated USB host controller (because you have a limited number of CPUs, and even with concurrent processing, activity on other USB busses will often slow down completion processing). Audio devices get around this by disciplining the clock at a higher level. It is easy to imagine a USB device that measures long term clock rate on the bus (using the SOF mechanisms or simply by pushing data over an isochronous pipe) and then feeds back clock difference information. (The device would schedule data to go to the host once per disciplined millisecond; this would either cause gaps in the isoch traffic, or overruns, which would be reported.) The driver on the host would use this to monitor clock drift and feed the information into the kernel clock. But using a serial port handshaking line over an emulated com port over USB is not likely to be terribly wonderful. Long-term accuracy (tick count) probably no problem, but jitter it will depend on how that's filtered. I suspect that the kernel's clock discipline loop is not likely to be happy if there's jitter on this particular reference. Best regards, --Terry -Original Message- From: tech-kern-ow...@netbsd.org [mailto:tech-kern-ow...@netbsd.org] On Behalf Of Mouse Sent: Friday, November 01, 2013 14:05 To: tech-kern@NetBSD.org Subject: Re: pulse-per-second API status * ucom(4) needs pps support It does? I thought USB introduced delays which are both uncertain and, in this context, large, [...] The delays introduced by USB are said to be on the order of 1 ms. I find said to be somewhat less than reassuring. It's been a while since I read the relevant doc, but I think this depends heavily on how often the host interface is configured to poll the device. The fuzzy memory also reports that there are different intervals configurable; I don't remember what they were, but I also don't know what NetBSD does for that, so that doesn't mean much. Also, see below - 1ms strikes me as pretty bad for PPS. [in another message] This patch to netbsd-5 adds pps support to ucom(4), [...] I have tested it with a GR301-W and the in-tree (-5) ntpd. I am seeing offsets of about -100ms [...] 100ms is a lot worse than 1ms, and surely bad enough that stamping the implicit approval of it's in the tree on this is a bad idea. Or do you really think your network is bad enough that 99ms of that is coming from network asymmetry? PPS with a lot of wobble in it may be better than a crappy network connection. But if NetBSD enables PPS on ucom, there's going to be an expectation that it is good enough for stratum-1 timekeeping, like PPS on real serial ports. You, Greg, know better. J-randoms who see what looks to them like PPS support on ucom won't. [back to the first message] So it depends on whether 1 ms of fuzz is doesn't work. Not quite: it also depends on how close (your impression of) what [is] said to be is to reality. I would say that if the next best option is worse than that (nmea timecode over the same USB, or asymmetic delays over the Internet), then it does work, even if a real serial port would be better. It does work in the sense that it's the best chime available in that dismal a situation. But it still may not work in the sense of living up to the expectations people have come to have for PPS on serial ports. My worry is not that
RE: pulse-per-second API status
I wasn't commenting on advisability of putting it into NetBSD. Just responding because I had, for a change, something relevant to contribute. (I actually know, in this case, what I'm talking about!) If the time info is presented into NTP using the same interface that network packets use, then jitter will be pretty well damped (and will be less, in any case, than typical network packet transport jitter). It is totally an application question as to whether this is good enough. I was assuming that, since the jitter on local interrupts is much less than on network packets, that there might be a different PLL tracking the data, as there are lots of tradeoffs here. But if it works well, by all means use it. And I know Mouse is more careful than I tend to be about terminology and so forth; he is, if I understand correctly, arguing that PPS directly connected is a lot different than PPS over USB, and so should be called something else. I don't have an opinion on that. I believe that for critical applications you'll get much less jitter using PPS directly connected; but I'd have to do experiments and my day job calls Best regards, --Terry -Original Message- From: tech-kern-ow...@netbsd.org [mailto:tech-kern-ow...@netbsd.org] On Behalf Of Greg Troxel Sent: Friday, November 01, 2013 15:30 To: Terry Moore Cc: tech-kern@NetBSD.org Subject: Re: pulse-per-second API status Thanks for the comments. Terry Moore t...@mcci.com writes: USB is not a very good way to do PPS synchronization if you're looking for usec resolution -- there are huge and unpredictable delays that can be introduced from a number of sources. Agreed, but that's not the question on the table. It's Should NetBSD support gathering timestamps from DCD transitions on ucom(4) devices using the RFC2783 API, or should it refuse to support that (on the theory that we are certain that anyone who tries to use it is thereby worse off, even though we do not understand their situation)?. Thanks for the summary of issues. I did not know all of those details, but did not find them too surprising. Still, it seems that there will often be less than 1 ms of trouble in many situations. But using a serial port handshaking line over an emulated com port over USB is not likely to be terribly wonderful. Long-term accuracy (tick count) probably no problem, but jitter it will depend on how that's filtered. I suspect that the kernel's clock discipline loop is not likely to be happy if there's jitter on this particular reference. The normal config would use ntp, which has filtering, and in my case it seems decent, showing 155 us of jitter (it varies, but almost always seems under 500 us). remote refid st t when poll reach delay offset jitter == oPPS(0) .BLOX. 0 l9 16 3770.0001.359 0.155 +[redacted s1] .TRUE. 1 u 19 64 377 95.7506.153 0.797 I should hook up a serial pps also, to compare, in addition to trying this within a few network ms of a believed-ok s1. But the above seems better than reading a serial timecode with a fudge.
RE: Lua in-kernel (lbuf library)
Yet again, this whole story just makes me wonder why AWK has never evolved to be more powerful language for this kind of purpose (Perl is not the direction I am talking about). Certainly, simplicity of AWK is valued. However, it does not mean that it should have just stopped evolving at some point in history. Even if its functions use 1-origin for arrays, the language itself is much more natural for the C programmers and the UNIX world. Personally, I would love to see more advanced AWK with just-in-time compilation.. Indeed, we started with Lua because AWK was not embeddable and because of the 1-origin issue. (Also, because Lua supports closures; closures are really a very economical way of expressing certain kinds of operations.) But we had 10 years or so of using AWK, wrapped by sh, as a cross UNIX platform. Unfortunately, it didn't work well for Windows in those days. And sh scripts still don't, Cygwin notwithstanding. But for many things we still use AWK. --Terry
RE: Lua in-kernel (lbuf library)
Just to clarify a bit Indeed, we started with Lua because AWK was not embeddable and because of the 1-origin issue. We thought, mistakenly, that a language that didn't look very much like C would cause fewer problems because of the 0-origin / 1-origin difference. Apparently, however, it's a deeper habit of thought. Ditto for the string escape sequences. Apparently the '[' and ']' for indexing, and the '\' for character escapes, trigger very deeply seated patterns. Based on our experience, it seems risky to use Lua to implement code that interoperates with kernel-like C code in security-critical contexts. We found this risk to be insurmountable. Engineers who are used to zero-origin code, and who are looking at zero-origin code for reference, will make zero-origin mistakes. This is not an argument against using Lua in user mode. However, given that the motto of NetBSD for kernel work is read the source, I worry that this human-factors issue will be hard to mitigate when using Lua in kernel mode. --Terry
RE: Lua in-kernel (lbuf library)
HI, I'm replying to a message that was on tech-userlevel@. I'm not sure why a discussion of in-kernel Lua was on tech-userlevel@. I see that other related messages were on tech-kern@, so I'm posting my reply there. My company has quite a bit of experience using Lua as a scripting language -- since 2000. Lua has many advantages and I like it very much. But it was really, really difficult for our embedded C programmers to use. We found the following areas of constant problem: 1) zero origin versus 1-origin arrays were a constant source of bugs, particularly when interoperating with C code. 2) the string escape sequences are almost but not completely compatible with C. In particular, in C, \123 is interpreted as octal, but in Lua \123 is decimal. This was a constant source of trouble. 3) the fact that a reference uninitialized variable or missing array element returns nil instead of throwing an exception is problematic for writing significant code that is intended to be reliable -- errors are hidden. 4) the Lua APIs are not a platform -- they change from version to version. (Working with Lua APIs and trying to track current is like working with certain open-source kernels -- you really can't maintain your investment.) And so forth. All of these decisions are actually fine, in context of a scripting language that's a world unto itself. But as a tool to give C programmers, they collectively were a real barrier to adoption. To address this, and to make it more palatable to our developers, after two years or so of experience (in 2002) MCCI forked the Lua interpreter and created a C-like variant (with renamed, stable APIs to address #4, and C-like syntax). There was a paper on this at the Lua conference in 2008: http://www.lua.org/wshop08.html#moore With that, we've been happily using something based on Lua, and I can agree with all the Lua enthusiasts: it's a great tool. If we weren't an entirely C-based company, we would not have bothered with the language changes (though we might have created stable APIs with non-clashing names). I'm not promoting our version as a solution. I am, however, pointing out that items #1 and #2 above merit careful consideration before putting Lua into a security-critical environment; C programmers won't like reviewing the code (and will tend to miss things). Best regards, --Terry -Original Message- From: tech-userlevel-ow...@netbsd.org [mailto:tech-userlevel- ow...@netbsd.org] On Behalf Of Mouse Sent: Wednesday, October 16, 2013 13:18 To: tech-userle...@netbsd.org Subject: Re: Lua in-kernel (lbuf library) [...0-origin vs 1-origin arrays...] It is hard to tell what is the least astonishing here. Well, least astonishing to whom, is really the question, it seems to me. Certainly I, as a C coder with no Lua experience, would find 0-origin arrays less astonishing. Someone with the converse experience would presumably have the opposite reaction. You propose Lua as a language embedded into C rather than separate one. I'd say that Lua designers made wrong decision here. Only if you think of Lua as being designed for embedding in C. It's just as coherent to think of the mistake as being trying to wed a language with 1-origin arrays with a language with 0-origin arrays. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML mo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: enumeration of bicycle sheds
Sorry, misread original comment -- C89 appeared as C99. Old eyes can be as bad as old ears for intelligent discussion --Terry t...@mcci.comtel: +1-607-277-1029fax: +1-607-277-6844www.mcci.com On 2/18/2010 8:18 AM, Iain Hibbert wrote: On Thu, 18 Feb 2010, Terry Moore wrote: Looking at C99, trailing commas _are_ allowed in enum lists. I know that, but C89 expressly forbade it and apparently C++ is similar. I'm not claiming that its reasonable and incidentally, share/misc/style says to not use the comma.. If you or anybody wants to argue for or against enum vs #define for lists of internal state variables, please go ahead. If the type checking for enum was strong enough that enum val { FOO, BAR }; int v = FOO; or enum val { FOO, BAR }; enum val v = 3; actually caused warnings then I would be more inclined to use it. In the meantime, I generally prefer #define but am not greatly attached. iain