"What UNIX Cost Us" - Benno Rice (LCA 2020)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome bin our rice so yeah after last year I thought I'd go a bit less controversial anyway so I thought I'd start in in good form by stealing something from Gary Bernard Gary Bernard is the author of the black talk if you haven't seen that see that then watch Katie's talk about explaining the wets but at the keynote that he gave at PyCon in Montreal few years back he talked about the state of knowing things but also the state of knowing that you know them and he put up this kind of truth table thing about whether you know something whether you met her know it and you know if you if you know it if you know something you know then you know it then it's a no not-it's knowledge it's it's it's there a saying you can use if it's saying you don't know but you know that you don't know it that's a known unknown that's something if you can go and find out later if you need to that's all good if you don't know it and you don't know that you don't know it then it's an unknown unknown in that saying that might come to bite you later on but there's a row missing from this what happens if you know something but you don't know that you know it Guerry to find that his ideology and I think that's a pretty good definition but on tradition I think is also somewhat appropriate there it's something where it's the kind of background radiation and it's something that you just use without really questioning it and so to get started let's so I work I work for a company that makes a lot of USB devices one of our USB devices which is not the key that you've got in your things it's a hierarchy sorry hardware storage module involves a piece of software we call the connector and it talks to it over USB and I was wanting to rewrite that in rust because you do and the problem was that at the time the leave us be bindings for rust were somewhat bit rotted and so I decided to try and implement just enough of what Lib USB did in rust itself on the three platforms that we cared about which were Windows Mac and Linux and basically I just wanted to implement this I want to iterate over the USB devices to find a device that matches are given vendor product tuple I want to get the devices serial number because sometimes you want to we have more than one attached we want to make sure we're attaching the right one on to open the device in plane interfaces zero USB devices can multiple it doesn't matter send an echo request pack and get the response back all good so here in fairly quick terms cuz otherwise I'm gonna blow my entire runtime on just this is what that code looks like without any error checking or anything do not run this code windows we start by getting a class device thing we enumerate we create an enumerator for it we get some devices we get interface detail not once but twice because the first time we're just trying to get a byte count so we do it again once we've got that then we have a device park this is not a filesystem part this is a device part this is not slash so dev slash something or the Windows equivalent it's like the device tree path that you get so that's all good then we open that with create file W the W means wide or Windows or something it means not ASCII and that's about the only actual file operation you'll see in this whole thing because we rapidly move on to the win USB API which is the u.s. the API for talking double USB devices from user space in Windows so we create an interface handle we get the device descriptor which gives us the vendor and product things that we need in order to be able to tell whether we got the right one then we get a string descriptor this 409 value is one you'll see a lot that is USB speak for English so we're getting the English serial number not any of the other fancy serial numbers then we make sure it's the one we want this is actually in utf-16 for reasons but whatever so now we've got the device we want we do a bunch of mucking around or setting pipe policies pipes of the things you use to communicate with the USB device this one tells it that we wanted to send zero-length packets when necessary this one and this one are all about just clearing the pipe to make sure that it's not going to fail on us and then we can write data to it and read data from it so that's not so bad like I was actually pleasantly surprised by this because it's not too bad you've got a bit at the start where you are doing the device iteration and finding the device you're looking for and then you've got the actual USB stuff on the other side and that's yeah it all flowed together pretty well so Mac we start by creating a dictionary this which is used for matching devices we tell you want to match USB devices then we go and find all the matching services or services a thing that lets you talk to a device we iterate over these and then we create plug-in interface for service this returns us an object that we can use to communicate with the device this is a comm object as in component object model I'm not making that up but it's for a good reason because at lesson version the interfaces you'll notice just above the bit I've highlighted it says K IO USB device interface ID 650 that means version 650 which pertains to mac cost 10 point something I can't remember so we have to call query interface which is comm speak for actually I want this class not the one you gave me at which point we don't need it anymore and we can go on and do something else with it so now that we've got our device we can call get device vendor and get device product that lets us find we've got the one we want then we can call get USB get serial number string index which tells us where in the string table the thing is and then we have to construct an actual request structure in order to get it which we then send you'll notice there's a lock at a lot of see structure function calling here that's all fine you make sure you got the right one and then then the next fun part is we have to create interface iterate because we have to eat irate over the interfaces that the device is giving us so this is another one of our kids iterators so we're calling io iterator next again that construction is merely tell me what interface number you are so that I can check it and then we get another one except this time instead of getting a USB device interface we're getting a USB interface interface factory again we have a it's version you know it's all actually not too bad and then we can open the interface and then I'm going to gloss over a bit which is the fact that Mac cos uses pipe indexes and you have to work out whether it's the part number you actually want but you just call right pipe and read pipe and the tio means that you're giving it a timeout that's all fine these are all if you actually go digging through Lim USB you will see all of this code with actual error checking and stuff so use that code not my code so how about Linux we start with you dev you Deb is not too bad you don't you you'd over numerate knew and you know we're creating an enumerator we're telling it we want USB devices we're scanning devices we get a list we user eight through the list we get a name which gives us a path and then we created you dev device from that path and then we get a bunch of things bus num dev adder insist name okay now what SN printf so we have to get to the file that contains the descriptors and then read the descriptor in at which point we can say whether we've got the right vendor and product tuple yes in printf so now we've got the actual device device and at that point the developers of this gave up on everything being a file and just made you write out big long structures and I octal it but now we've got the serial number so that's okay and then another eye octal so that's the claim interface that's to do the right one and then read and write is you guessed it i'ope dolls so yeah I'm not a fan that everything is a file mentality that they've used here I don't think has actually served them well at all the UDV interface was quite nice but as soon as I had to pivot through SN printf using paths that I had to work out myself in order to actually work out where the device was that that didn't really work too well but this is not the worst us be related or everything is a file API that's around the USB function FS is used to create user space devices so I wanted to test the code that I'd written that meant I needed a USB device that I had on a stick and could control and control our responses off linux has an answer for that it's called the function FS API here's what you need to do you have to make a magic directory you have to make more magic directories you have to echo random values into files have got magically created when you created those magic directories you have to sim link one of your magic directories to another magic directory you have to then make another magic directory Mountain magic filesystem then you have to write a bunch of carefully constructed binary data shove it into a file which then creates more devices at which point you can open those fight those devices and start doing stuff with them at which point you cat our magic value that's dependent on your system into another magic file and hopefully it connects [Applause] it's yeah my colleague Nigel is here if you want to see if you can ask him afterwards how much I was swearing as I tried to write this in a way that was repeatable so so I mean one could argue that mic my problems with the Linux USB API are covered off by the fact that everyone is uses live USB and you can say the same thing about C groups because C groups has a somewhat alarming file based UI API sorry and it's also covered by a library and that's fine but it's still not like it's indicative of a mindset that's gone into this where we've taken this notion that it's kind of fun when everything is a file and it worked for /dev and it kind of work for /proc but it sucked and then we just kept going with it because it was the obvious thing to do and part of it I think is that UNIX never really specified how we're supposed to do that kind of thing it was very concerned with a whole bunch of other stuff but it never sat down and said how do you actually configure a system and so you know I think it's just indicative of people get into this railroaded mindset where they just don't think that they could do something another way but anyway let's talk about stuff that UNIX did standardize so one of the the job titles for this when I first started writing it was Dave Cutler was right for those of you who don't know Dave Cutler was originally with Dec and then went to Microsoft where he created this little operating system called Windows NT and he was not a fan of Unix and he was especially not a fan of UNIX as i/o model where he had his joke apparently where he said would say got a byte got a byte got a byte by byte but anyway so this is this is the UNIX I oh I oh I like the guts of it and this works reasonably well when you think about it running on something like a VAX or a PDP or something like that you're reading some data and you writing some data out it's really simple everything's great then the internet happened or more importantly people discovered that shoveling out of sockets and into sockets and into files and how-to files in lots of different ways didn't really work with that API very well because it's blocking a file descriptor in UNIX by default we'll block when you read the read call does not return until it's done its reading when you write it doesn't return until it's done its writing and this slows you down because you can only do one thing at a time but we have an answer for that that's fine we have the most delightfully named system calling the entire UNIX Pantheon which I won't pronounce which we can use to set a flag that says we shouldn't block at which point we can use the wonderful select API which showed up in the 4.2 BSD in 1983 the problem with this one is that you have to shovel these FD sets which are effectively large bit strings one bit per file descriptor into and out of the kernel and they also have you also have to know how big they are which kind of limits how many file descriptors you can have and that's great when you're talking small things but because you know let's not forget UNIX predates the internet and so you know that was okay but it didn't work too well AT&T is response was as with ESP r3 and 1986 was Paul this fixes the file descriptor cap problem but it means he still had to shovel large amounts of file descriptor records in and out of the kernel and all that kind of stuff so it still had performance limitations and then we had a bit of a and then FreeBSD I in 2000 invented this API which was actually really good it's a kernel event API it's not just father the script or events it's all kernel events you can register to listen for any of them and get them all back that's file descriptor events file events like you know this file got created deleted processes exited signals happened all kinds of stuff and of course this was so this was really good it was used to make a whole bunch of nice high performance stuff on FreeBSD so of course leanest said hell no I'm not taking that a poll is okay I guess except it's very focused around file descriptors and so if you want anything else to be an event you have to create a file descriptor for it because all events are files anyway but anyway that's that's kind of a side the point now we have non-blocking i/o and that's great but the thing is this i/o is still synchronous synchronous is different to blocking blocking means that you can't do anything else until you finish doing the first thing synchronous means you still have to wait for it to finish it's just my finish and say I couldn't do it right now and this is really almost tied in with the UNIX process model where processes memory is like it's not strictly sacrosanct but it's it's generally not good form for the kernel to go rummaging around in your memory a lot and asynchrony would require that to be the case you would have to be able to muck around in your protein the processes memory and have a memory that's shared between two things at once and that's tricky now it didn't stop posite from having a go hands up who's actually used this api yeah not many but on the flip side that's the Windows equivalent of those calls but ever since NT 3.5 as in the first release people did it there's also been these those are asynchronous they have a completion handler you can do stuff with that and then when windsock to also had similar things and we also they also had completion ports and so that's basically a thing that you listen on and when your iOS finished you get a notice that it happens and even they have a solution to the I have to open the file descriptor so I can write a bite out it to wake my event loop up problem by just posting your own completion event and I mean the part of this the part of the problem here is that UNIX is stuff is all tied to its history like it grew out of systems that were very simple and Windows does have an unfair advantage here in that it came along both after unix and after VMS and after a whole bunch of other things where it could learn from it but the real that my problem with this is not so much that it's more that we haven't really caught up when you have a look at what happens on hood of light but the kernel level as opposed to the user level IO is really interesting this is this is a really bad description of a descriptor ring most modern IO hardware we're talking scuzzy cards or solder cards Nix nvme all users descriptor rings like this in memory you allocate a block of memory and you carefully miss a line one of the lines of that anyway and each one of those is to 64 byte values you generally have a buffer address and some metadata you might this varies a lot based on hardware but once you've got that you have a host pointer and a device pointer the host moves through and fills in the the buffer rent addresses and each buffer address points at some data that might be written out or an address where the device can write data to and then as the device sees it those are there it can move along and fill them in and then the host can go back and find the ones that do use it and it just loops around at the end and keeps going if the ring fills up then you have to wait for stuff to go through and Linux now has as of some very short time ago IOU ring which actually does do an 8 an IO API that follows those principles and I think that's great but the real issue for me here is that could have happened a long time ago these Hardware descriptor rings have been around for years but I think there's a combination of again just being stuck in the mindset of where we were before but also just not wanting to rock the boat and a lot of people thinking in a much higher level these days then the low-level i/o api's that means that we that we don't always take the advantage inity to progress these things when we can but that's sort of at that level let's go a little deeper so I told you I was going for you know less controversial so I want to start this section with a reading from nm Banks's book accession in which he describes the concept of an outside concept problem the usual example given to illustrate an outside context problem was imagining you are a tribe on a large fertile island you tame the land invented the wheel or writing or whatever the neighbors are cooperative or enslaved but at any rate peaceful and you were busy raising temples to yourself with all the excess product to capacity you had you're in a position of near absolute power and control what your halide ancestors could hardly have dreamed of in the whole situation was just run along nicely like a canoe on wet grass when suddenly this bristling lump of iron appears sail or some trailing steam in the bay and these guys carrying long funny-looking sticks come ashore announce you've just been discovered you're all subject to the Emperor now his keen on presence called tax and these bright-eyed holy men would like a word with your priests so obviously this has a lot to do with sea so now I'm going to talk about farming specifically I'm going to talk about farming in Europe so in Europe they did a lot of farming they got pretty good at it and then they got really good at building ships and so they got on their ships and went out and found that there were other places they could go and they decided they looked like the look of some of those other places and so they went there and they got there and they went right we're gonna farm this place good thing there's nobody else here we'll just we'll just do some farming like we did back home and it didn't work out so well and it's not because the people weren't there it's because they had been there for a while you should read this book it talks about how the indigenous people of Australia had been farming quite happily until white folks showed up but the trouble is it's kind of almost an inversion of this outside context problem where the outside context doesn't come to the people the people come to the outside context and suddenly everything they knew doesn't work anymore so this is a pdp-11 this is what c was born on the pdp-11 is a single inorder cpu with a very flat uncomplicated memory and when I'm talking like single in order I mean like almost like the the ridiculously simplified diagram of the CPU that we get occasionally like earliest models of VBP Levin didn't even have a clock when you wanted to read from memory the CPU would set some address bits strobe some things and then the data would come back and it would move on to the next instruction and so you know it's fairly straightforward it's a very simple lockstep execution thing there's no cache there's no memory hierarchy it's just you read a byte from the memory and then you might read a bite from an i/o device and you might add them together and then you might put them somewhere else the thing is that time happens and the pdp-11 baguettes the VAX and the vaccine fluence is the 8086 and then a whole bunch of stuff happens and you end up with an AMD 64 device and this isn't an AMD 64 device but this is what a cortex 877 looks like inside in a very very simplified form you will note that this is not a simple inorder CPU with a flat memory hierarchy you've got instruction decoders you've got branch predictors you've got dispatching things you've got you've got to two words that 10 generally show up through sort of the 90s of superscalar and pipelined and this it has both of them in spades super scalar refers to the fact that you've got all of these units up the top here that can all do different things at the same time and then pipelining means that you've got instructions moving at various stages through an execution pipeline at once and new instructions come into the pipeline as you go through what does this mean it means that in order to make C run fast you have to do things that lie about the underlying execution architecture of what you're actually on you're not in Europe anymore and this leads to things like Spector and meltdown because suddenly you're lying about the the actual state of the machine in order to make it go fast but that the stuff that you're doing still has ripple effects that go through that can be measured and that can lead to information you can get C is not built to handle this and a whole bunch of the problem is that we are trying to make a system that looks sufficiently like a PDP 11 but is still really fast and the things that we do to make it fast make it break and there are there are other things that C is not good at sorry let me start that again there are ways that we could make it better but they would involve abandoning things that make CC for example doing good vectorization means you can do some kinds of loops really fast fortran is really good at this because it knows how big is big its arrays are and it has some more guarantees about what things are independent from what other things and so it can go really fast which is why for train is still used in numerical analysis in ways that c isn't when you use things like numpy or pandas a lot of the underlying routines that you're using to do that are actually written in Fortran another one that gets in the way is that C causes prawns with is structure layout and padding C has arcane rules about how structures get laid out and padded and they cause a whole bunch of problems because you can't then necessarily treat elements in structures as independent variables which slows things down again and that's even before you get on to all of the other fun of C and the real thing is we're just you know we're not on a pdp-11 anymore even as much as we'd like to pretend it and the core point of this is that C while it was useful at the time because when you think about what C came out of you had to have a very limited language set because it was running on very small computers it was running on a very simple thing but we've failed again to progress beyond what we could do with that and it's gotten even worse in this case because it's we've ended up in this self reinforcing loop where we make CPUs that are designed to run C fast which means we can't change C because then we might not be able to do the pro that might be able to make yeah might not be able to write code that goes fast on those CPUs and to change one involves changing the other but we do have things that do look different now we have GPUs we have things with a lot more vector hardware and we have languages that are evolving to be able to take use of those I mean rust is an obvious example I'm not gonna tell everyone to go and switch to rust I don't even know if Russ is gonna be the long-term solution to this but I think looking at the language and being willing to make changes to it is an important thing before I move on there are two things you should look up here I've taken a lot of this inter stuff from a post called C is not a low-level language which is well worth a read and a lot of the stuff on farming and colonialism I got from Sarah Taber who is well worth the follow on Twitter and that's a podcast there but again I think there are problems that go even deeper so half the problem with the UNIX philosophy is what even is it like there are a number of different definitions they all tend to involve a whole bunch of things I went actually looked around there's this one which I think is the earliest one I found so making it easy to write write write test and run programs interactive views instead of batch processing economy and elegance of design due to size constraints salvation through suffering that's a very Protestant of them and self-supporting and then this sort of evolves into we start seeing things that we actually more associate with the UNIX philosophy make each program do one thing well expect the output of every program to become the input islets if you're pipelining so and so forth we have Rob Pike's attempt at making it more complicated I think and then this is probably the simplest one that I found write programs that do one thing and do it well write programs to work together write programs to handle text rings because that is universal everything notice that none of those says everything is a file and in general I mean from what I neared the usual sort of surface sort of interpretation of the Enix philosophy is that you should be able to do this a lot oh you know or maybe that but the problem with that is that as a newbie I don't even know what that means and then I have to learn regular expressions and the thing is like you often see these things when you're trying to do system administration task was just fine but you know you know if I want to like as I do it you become a lot I have to kill my GPG agent because it just gets confused or in the way and so you know I'm gonna run PSA xww I'm gonna get some things there and crap I got my grep command as well as GPG agent so I'm gonna have to get rid of grep and now that I've got that I have to actually get the peared so I'm gonna have to pipe it through auch or something and at that point I can actually kill the damn thing now I'm on a Mac though so I can hit command space and get spotlight and type a few characters and get effectively the same thing and then type some stuff in here and then click a button now it's actually quicker and it's a lot easier to explain to someone than explaining what grep is and I think the UNIX philosophy in its expression of doing one thing and doing it well and all that kind of stuff is a useful starting point that it really comes in to the interpretation of where you're going with that and I think the trouble that we get is that people get too locked into it they get too caught up in the purity of it and don't get and they're insufficiently pragmatic and in themselves in knots like the USB function FS interface I showed you before and it UNIX is not the only thing to have this kind of a philosophy thing I mean the Zen of Python is actually really useful in a bunch of ways but again python has a old Python like UNIX has a bunch of things that aren't expressed in the Zen of Python that tend to make life difficult for it Chris gave a talk at PyCon a year last year called fantastic blocks and where to hide them where he does talk pythons philosophical objections to blocks despite the fact that it has them it just doesn't know what to do with them and I think that that's you know it's again getting locked into a particular mindset without actually sort of interrogating it so the problem with the UNIX philosophy that I have is that the people who may tend to express it the most enthusiastically tend to express in a way that ends up being almost universally user hostile all of the things that I like about using computers these days tend to be things that violate the UNIX philosophy of doing one thing and doing it well because when you abandon that you can start to glue things together in ways that make things nice and easy to use and quick I quite like Matt Goss these days well I've liked it for quite a while and I would I should have pasted in the xkcd strip of a chart of my satisfaction of how my life is going versus how long it's had how long since I've opened X or conf because that's that's a usual argument that I give to people and they ask why I use a Mac and not FreeBSD or Linux on my desktop and again it comes down to getting blinkered about the way that we think and feeling that there is no other way to think so to finish up a lot of this has just been me you know ranting it is a beautiful day at the conference in Iowa horrible curmudgeon but when we get down to it unikz suited its time it was the right operating system for the right people at the right time and then through an accident of bureaucracy it became the thing that we all use to some extent greater or lesser and that's a wonderful thing but I worried that it has ended up straight jacketing the way that we think because that time was actually quite a while ago it still works which is amazing but that doesn't mean that it's tenets and its way of thought should be sacrosanct we should feel free to examine every idea and throw them out if we feel that they no longer have value for what we're doing and that extends beyond things that are purely technical like UNIX a lot of the ways that our communities got built up over the years like I remember a time when this was not a dirty word if it's not a dirty word for you now it should be meritocracy is a lie but I remember back in the mid to late 90s almost every community that was a part of would use this as one of their foundational concepts we don't see gender we don't see race we don't see sexuality we just see the ability that you have for code but I unexamined underneath that was the reason that you only don't see gender or race or or sexuality is that your community is full of straight white men and as soon as the people who weren't straight white men either showed up or stopped being Anonymous figures on the internet and revealed themselves to not be straight white men suddenly this became a problem and so you have to under you have to then think about what merit actually means are these peoples not showing merit because they're bad or are they're not showing merit because we've set up a systemic structure that stops them from being good or allowing them to be good and then we try to fix this by bringing in codes of conduct and the howls and the howls because why should I have to be shackled to this code of conduct because I've always been a good person I thought and that's you know that that's a problem and then the other problem that I have is that people don't like to resort to the pithy philosophical thing like the Zen you know the Zen of Python is great but it requires interpretation as does the UNIX philosophy and so if anyone comes up to you and tells you that your code of conduct only needs to be be excellent to each other you need to tell them to go away because under unspoken beneath this is who must be excellent to whom if I if I bait you by you know calling you slurs or saying like that until you explode at me in a fit of rage that you have quiet that I have quite rightly earned have you been excellent to me and at that point can I run to my governing body and say oh I'll they yelled at me they yelled at me come out and conduct and the community management requires a lot more sensitivity and a lot more nuance than that and so in both community and technical sense it's safe to say that complex problems have simple easy to understand wrong answers and that we should understand the past because it's important to know it because so you can learn from it but you it's you can't let it bind the future because that just closes things off as Sean Brady said in his keynote yesterday it's important to learn that sometimes you can drop your tools and try and make new ones and thank you very much if anyone does want to tell me you come and talk to me feel free to find me out there I will say though that if you want to lecture me and tell me I'm wrong you have to buy me a drink first well thank you very much we've got a small gift a token of our appreciation if we do have a few more minutes to go it's not actually time up yet so if you do want to have a question just put your hand up and I'll borrow the microphone No [Applause]
Info
Channel: linux.conf.au
Views: 67,980
Rating: undefined out of 5
Keywords: lca, lca2020, #linux.conf.au#linux#foss#opensource, BennoRice
Id: 9-IWMbJXoLM
Channel Id: undefined
Length: 34min 14sec (2054 seconds)
Published: Wed Jan 15 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.