News aggregator

Jonathan McDowell: On my way home from OMGWTFBBQ

Planet ALUG - Sun, 27/08/2017 - 18:42

I started writing this while sitting in Stansted on my way home from the annual UK Debian BBQ. I’m finally home now, after a great weekend catching up with folk. It’s a good social event for a bunch of Debian folk, and I’m very grateful that Steve and Jo continue to make it happen. These days there are also a number of generous companies chipping in towards the cost of food and drink, so thanks also to Codethink and QvarnLabs AB for the food, Collabora and Mythic Beasts for the beer and Chris for the coffee. And Rob for chasing us all for contributions to cover the rest.

I was trying to remember when the first one of these I attended was; trawling through mail logs there was a Cambridge meetup that ended up at Steve’s old place in April 2001, and we’ve consistently had the summer BBQ since 2004, but I’m not clear on what happened in between. Nonetheless it’s become a fixture in the calendar for those of us in the UK (and a number of people from further afield who regularly turn up). We’ve become a bit more sedate, but it’s good to always see a few new faces, drink some good beer (yay Milton), eat a lot and have some good conversations. This year also managed to get me a SheevaPlug so I could investigate #837989 - a bug with OpenOCD not being able to talk to the device. Turned out to be a channel configuration error in the move to new style FTDI support, so I’ve got that fixed locally and pushed the one line fix upstream as well.

Categories: LUG Community Blogs

Jonathan McDowell: Notes on upgrading from Jessie to Stretch

Planet ALUG - Tue, 22/08/2017 - 20:29

I upgraded my last major machine from Jessie to Stretch last week. That machine was the one running the most services, but I’d made notes while updating various others to ensure it went smoothly. Below are the things I noted along the way, both for my own reference and in case they are of use to anyone else.

  • Roundcube with the sqlite3 backend stopped working after the upgrade; fix was to edit /etc/roundcube/debian-db-roundcube.php and change sqlite3:// to sqlite:// in the $config['db_dsnw'] line.
  • Dovecot no longer supports SSLv2 so had to remove !SSLv2 from the ssl_protocols list in /etc/dovecot/conf.d/10-ssl.conf
  • Duplicity now tries to do a mkdir so I had to change from the scp:// backend to the sftp:// backend in my backup scripts.
  • Needed to add needs_root_rights=yes to /etc/X11/Xwrapper.config so Kodi systemd unit could still start it on a new VT. Need to figure out how to get this working without the need for root.
  • Upgrading fail2ban would have been easier if I’d dropped my additions in /etc/fail2ban/jail.d/ rather than the master config. Fixed for next time.
  • ejabberd continues to be a pain; I do wonder if it’s worth running an XMPP server these days. I certainly don’t end up using it to talk to people myself.
  • Upgrading 1200+ packages takes a long time, even when the majority of them don’t have any questions to ask during the process.
  • PostgreSQL upgrades have got so much easier. pg_upgradecluster 9.4 main chugged away but did exactly what I needed.

Other than those points things were pretty smooth. Nice work by all those involved!

Categories: LUG Community Blogs

Daniel Silverstone (Kinnison): Building a USB descriptor table set

Planet ALUG - Tue, 22/08/2017 - 10:58

In order to proceed further on our USB/STM32 oddessy, we need to start to build a USB descriptor set for our first prototype piece of code. For this piece, we're going to put together a USB device which is vendor-specific class-wise and has a single configuration with a interface with a single endpoint which we're not going to actually implement anything of. What we're after is just to get the information presented to the computer so that lsusb can see it.

To get these built, let's refer to information we discovered and recorded in a previous post about how descriptors go together.

Device descriptor

Remembering that values which are > 1 byte in length are always stored little-endian, we can construct our device descriptor as:

Our device descriptor Field Name Value Bytes bLength 18 0x12 bDescriptorType DEVICE 0x01 bcdUSB USB 2.0 0x00 0x02 bDeviceClass 0 0x00 bDeviceSubClass 0 0x00 bDeviceProtocol 0 0x00 bMaxPacketSize 64 0x40 idVendor TEST 0xff 0xff idProduct TEST 0xff 0xff bcdDevice 0.0.1 0x01 0x00 iManufacturer 1 0x01 iProduct 2 0x02 iSerialNumber 3 0x03 bNumConfigurations 1 0x01

We're using the vendor ID and product id 0xffff because at this point we don't have any useful values for this (it costs $5,000 to register a vendor ID).

This gives us a final byte array of:

0x12 0x01 0x00 0x02 0x00 0x00 0x00 0x40 (Early descriptor)

0xff 0xff 0xff 0xff 0x01 0x00 0x01 0x02 0x03 0x01 (and the rest)

We're reserving string ids 1, 2, and 3, for the manufacturer string, product name string, and serial number string respectively. I'm deliberately including them all so that we can see it all come out later in lsusb.

If you feed the above hex sequence into a USB descriptor decoder then you can check my working.

Endpoint Descriptor

We want a single configuration, which covers our one interface, with one endpoint in it. Let's start with the endpoint...

Our bulk IN endpoint Field Name Value Bytes bLength 7 0x07 bDescriptorType ENDPOINT 0x05 bEndpointAddress EP2IN 0x82 bmAttributes BULK 0x02 wMaxPacketSize 64 0x40 0x00 bInterval IGNORED 0x00

We're giving a single bulk IN endpoint, since that's the simplest thing to describe at this time. This endpoint will never be ready and so nothing will ever be read into the host.

All that gives us:

0x07 0x05 0x82 0x02 0x40 0x00 0x00

Interface Descriptor

The interface descriptor prefaces the endpoint set, and thanks to our simple single endpoint, and no plans for alternate interfaces, we can construct the interface simply as:

Our single simple interface Field Name Value Bytes bLength 9 0x09 bDescriptorType INTERFACE 0x04 bInterfaceNumber 1 0x01 bAlternateSetting 1 0x01 bNumEndpoints 1 0x01 bInterfaceClass 0 0x00 bInterfaceSubClass 0 0x00 bInterfaceProtocol 0 0x00 iInterface 5 0x05

All that gives us:

0x09 0x04 0x01 0x01 0x01 0x00 0x00 0x00 0x05

Configuration descriptor

Finally we can put it all together and get the configuration descriptor...

Our sole configuration, encapsulating the interface and endpoint above Field Name Value Bytes bLength 9 0x09 bDescriptorType CONFIG 0x02 wTotalLength 9+9+7 0x19 0x00 bNumInterfaces 1 0x01 bConfigurationValue 1 0x01 iConfiguration 4 0x04 bmAttributes Bus powered, no wake 0x80 bMaxPower 500mA 0xfa

The wTotalLength field is interesting. It contains the configuration length, the interface length, and the endpoint length, hence 9 plus 9 plus 7 is 25.

This gives:

0x09 0x02 0x19 0x00 0x01 0x01 0x04 0x80 0xfa

String descriptors

We allowed ourselves a total of five strings, they were iManufacturer, iProduct, iSerial (from the device descriptor), iConfiguration (from the configuration descriptor), and iInterface (from the interface descriptor) respectively.

Our string descriptors will therefore be:

String descriptor zero, en_GB only Field Name Value Bytes bLength 4 0x04 bDescriptorType STRING 0x03 wLangID[0] en_GB 0x09 0x08

0x04 0x03 0x09 0x08

...and...

String descriptor one, iManufacturer Field Name Value Bytes bLength 38 0x26 bDescriptorType STRING 0x03 bString "Rusty Manufacturer" ...

0x26 0x03 0x52 0x00 0x75 0x00 0x73 0x00

0x74 0x00 0x79 0x00 0x20 0x00 0x4d 0x00

0x61 0x00 0x6e 0x00 0x75 0x00 0x66 0x00

0x61 0x00 0x63 0x00 0x74 0x00 0x75 0x00

0x72 0x00 0x65 0x00 0x72 0x00

(You get the idea, there's no point me breaking down the rest of the string descriptors here, suffice it to say that the other strings are appropriate for the values they represent - namely product, serial, configuration, and interface.)

Putting it all together

Given all the above, we have a device descriptor which is standalone, then a configuration descriptor which encompasses the interface and endpoint descriptors too. Finally we have a string descriptor table with six entries, the first is the language sets available, and the rest are our strings. In total we have:

// Device descriptor const DEV_DESC: [u8; 18] = { 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01 }; // Configuration descriptor const CONF_DESC: [u8; 25] = { 0x09, 0x02, 0x19, 0x00, 0x01, 0x01, 0x04, 0x80, 0xfa, 0x09, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x05, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00 }; // String Descriptor zero const STR_DESC_0: [u8; 4] = {0x04, 0x03, 0x09, 0x08}; // String Descriptor 1, "Rusty Manufacturer" const STR_DESC_1: [u8; 38] = { 0x26, 0x03, 0x52, 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x72, 0x00 }; // String Descriptor 2, "Rusty Product" const STR_DESC_2: [u8; 28] = { 0x1c, 0x03, 0x52, 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00, 0x74, 0x00 }; // String Descriptor 3, "123ABC" const STR_DESC_3: [u8; 14] = { 0x0e, 0x03, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00 }; // String Descriptor 4, "Rusty Configuration" const STR_DESC_4: [u8; 40] = { 0x28, 0x03, 0x52, 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x69, 0x00, 0x67, 0x00, 0x75, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00 }; // String Descriptor 5, "Rusty Interface" const STR_DESC_5: [u8; 32] = { 0x20, 0x03, 0x52, 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, 0x00 };

With the above, we're a step closer to our first prototype which will hopefully be enumerable. Next time we'll look at beginning our prototype low level USB device stack mock-up.

Categories: LUG Community Blogs

Debian Bits: Work on Debian for mobile devices continues

Planet HantsLUG - Thu, 17/08/2017 - 13:39

Work on Debian for mobile devices, i.e. telephones, tablets, and handheld computers, continues. During the recent DebConf17 in Montréal, Canada, more than 50 people had a meeting to reconsider opportunities and challenges for Debian on mobile devices.

A number of devices were shown at DebConf:

  • PocketCHIP: A very small handheld computer with keyboard, Wi-Fi, USB, and Bluetooth, running Debian 8 (Jessie) or 9 (Stretch).
  • Pyra: A modular handheld computer with a touchscreen, gaming controls, Wi-Fi, keyboard, multiple USB ports and SD card slots, and an optional modem for either Europe or the USA. It will come preinstalled with Debian.
  • Samsung Galaxy S Relay 4G: An Android smartphone featuring a physical keyboard, which can already run portions of Debian userspace on the Android kernel. Kernel upstreaming is on the way.
  • ZeroPhone: An open-source smartphone based on Raspberry Pi Zero, with a small screen, classic telephone keypad and hardware switches for telephony, Wi-Fi, and the microphone. It is running Debian-based Raspbian OS.

The photo (click to enlarge) shows all four devices, together with a Nokia N900, which was the first Linux-based smartphone by Nokia, running Debian-based Maemo and a completely unrelated Gnuk cryptographic token, which just sneaked into the setting.

If you like to participate, please

Categories: LUG Community Blogs

Debian Bits: Debian turns 24!

Planet HantsLUG - Wed, 16/08/2017 - 15:50

Today is Debian's 24th anniversary. If you are close to any of the cities celebrating Debian Day 2017, you're very welcome to join the party!

If not, there's still time for you to organize a little celebration or contribution to Debian. For example, spread the word about Debian Day with this nice piece of artwork created by Debian Developer Daniel Lenharo de Souza and Valessio Brito, taking inspiration from the desktop themes Lines and softWaves by Juliette Belin:

If you also like graphics design, or design in general, have a look at https://wiki.debian.org/Design and join the team! Or you can visit the general list of Debian Teams for many other opportunities to participate in Debian development.

Thanks to everybody who has contributed to develop our beloved operating system in these 24 years, and happy birthday Debian!

Categories: LUG Community Blogs

Debian Bits: DebConf17 closes in Montreal and DebConf18 dates announced

Planet HantsLUG - Sat, 12/08/2017 - 21:59

Today, Saturday 12 August 2017, the annual Debian Developers and Contributors Conference came to a close. With over 405 people attending from all over the world, and 169 events including 89 talks, 61 discussion sessions or BoFs, 6 workshops and 13 other activities, DebConf17 has been hailed as a success.

Highlights included DebCamp with 117 participants, the Open Day,
where events of interest to a broader audience were offered, talks from invited speakers (Deb Nicholson, Matthew Garrett and Katheryn Sutter), the traditional Bits from the DPL, lightning talks and live demos and the announcement of next year's DebConf (DebConf18 in Hsinchu, Taiwan).

The schedule has been updated every day, including 32 ad-hoc new activities, planned
by attendees during the whole conference.

For those not able to attend, talks and sessions were recorded and live streamed, and videos are being made available at the Debian meetings archive website. Many sessions also facilitated remote participation via IRC or a collaborative pad.

The DebConf17 website will remain active for archive purposes, and will continue to offer links to the presentations and videos of talks and events.

Next year, DebConf18 will be held in Hsinchu, Taiwan, from 29 July 2018 until 5 August 2018. It will be the first DebConf held in Asia. For the days before DebConf the local organisers will again set up DebCamp (21 July - 27 July), a session for some intense work on improving the distribution, and organise the Open Day on 28 July 2018, aimed at the general public.

DebConf is committed to a safe and welcome environment for all participants. See the DebConf Code of Conduct and the Debian Code of Conduct for more details on this.

Debian thanks the commitment of numerous sponsors to support DebConf17, particularly our Platinum Sponsors Savoir-Faire Linux, Hewlett Packard Enterprise, and Google.

About Savoir-faire Linux

Savoir-faire Linux is a Montreal-based Free/Open-Source Software company with offices in Quebec City, Toronto, Paris and Lyon. It offers Linux and Free Software integration solutions in order to provide performance, flexibility and independence for its clients. The company actively contributes to many free software projects, and provides mirrors of Debian, Ubuntu, Linux and others.

About Hewlett Packard Enterprise

Hewlett Packard Enterprise (HPE) is one of the largest computer companies in the world, providing a wide range of products and services, such as servers, storage, networking, consulting and support, software, and financial services.

HPE is also a development partner of Debian, and provides hardware for port development, Debian mirrors, and other Debian services.

About Google

Google is one of the largest technology companies in the world, providing a wide range of Internet-related services and products as online advertising technologies, search, cloud computing, software, and hardware.

Google has been supporting Debian by sponsoring DebConf since more than ten years, at gold level since DebConf12, and at platinum level for this DebConf17.

Categories: LUG Community Blogs

Steve Kemp: A day in the life of Steve

Planet HantsLUG - Sat, 12/08/2017 - 21:00

I used to think I was a programmer who did "sysadmin-stuff". Nowadays I interact with too many real programmers to believe that.

Or rather I can code/program/develop, but I'm not often as good as I could be. These days I'm getting more consistent with writing tests, and I like it when things are thoroughly planned and developed. But too often if I'm busy, or distracted, I think to myself "Hrm .. compiles? Probably done. Oops. Bug, you say?"

I was going to write about working with golang today. The go language is minimal and quite neat. I like the toolset:

  • go fmt
    • Making everything consistent.
  • go test

Instead I think today I'm going to write about something else. Since having a child a lot of my life is different. Routine becomes something that is essential, as is planning and scheduling.

So an average week-day goes something like this:

  • 6:00AM
    • Wake up (naturally).
  • 7:00AM
    • Wake up Oiva and play with him for 45 minutes.
  • 7:45AM
    • Prepare breakfast for my wife, and wake her up, then play with Oiva for another 15 minutes while she eats.
  • 8:00AM
    • Take tram to office.
  • 8:30AM
    • Make coffee, make a rough plan for the day.
  • 9:00AM
    • Work, until lunchtime which might be 1pm, 2pm, or even 3pm.
  • 5:00PM
    • Leave work, and take bus home.
    • Yes I go to work via tram, but come back via bus. There are reasons.
  • 5:40PM
    • Arrive home, and relax in peace for 20 minutes.
  • 6:00PM-7:00PM
    • Take Oiva for a walk, stop en route to relax in a hammock for 30 minutes reading a book.
  • 7:00-7:20PM
    • Feed Oiva his evening meal.
  • 7:30PM
    • Give Oiva his bath, then pass him over to my wife to put him to bed.
  • 7:30PM - 8:00pm
    • Relax
  • 8:00PM - 10:00PM
    • Deal with Oiva waking up, making noises, or being unsettled.
    • Try to spend quality time with my wife, watch TV, read a book, do some coding, etc.
  • 10:00PM ~ 11:30PM
    • Go to bed.

In short I'm responsible for Oiva from 6ish-8ish in the morning, then from 6PM-10PM (with a little break while he's put to bed.) There are some exceptions to this routine - for example I work from home on Monday/Friday afternoons, and Monday evenings he goes to his swimming classes. But most working-days are the same.

Weekends are a bit different. There I tend to take him 6AM-8AM, then 1PM-10PM with a few breaks for tea, and bed. At the moment we're starting to reach the peak-party time of year, which means weekends often involve negotiation(s) about which parent is having a party, and which parent is either leaving early, or not going out at all.

Today I have him all day, and it's awesome. He's just learned to say "Daddy" which makes any stress, angst or unpleasantness utterly worthwhile.

Categories: LUG Community Blogs

Daniel Silverstone (Kinnison): STM32 and RTFM

Planet ALUG - Sun, 06/08/2017 - 16:23

I have been working with STM32 chips on-and-off for at least eight, possibly closer to nine years. About as long as ST have been touting them around. I love the STM32, and have done much with them in C. But, as my previous two posts may have hinted, I would like to start working with Rust instead of C. To that end, I have been looking with great joy at the work which Jorge Aparicio has been doing around Cortex-M3 and Rust. I've had many comments in person at Debconf, and also several people mention on Twitter, that they're glad more people are looking at this. But before I can get too much deeper into trying to write my USB stack, I need to sort a few things from what Jorge has done as demonstration work.

Okay, this is fast, but we need Ludicrous speed

All of Jorge's examples seem to leave the system clocks in a fairly default state, excepting turning on the clocks to the peripherals needed during the initialisation phase. Sadly, if we're going to be running the USB at all, we need the clocks to run a tad faster. Since my goal is to run something moderately CPU intensive on the end of the USB too, it makes sense to try and get our STM32 running at maximum clock speed. For the one I have, that's 72MHz rather than the 8MHz it starts out with. Nine times more cycles to do computing in makes a lot of sense.

As I said above, I've been doing STM32 in C a lot for many years; and fortunately I have built systems with the exact chip that's on the blue-pill before. As such, if I rummage, I can find some old C code which does what we need...

/* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); /* Wait till HSE is ready */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); if (HSEStartUpStatus == SUCCESS) { /* Enable Prefetch Buffer */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* Flash 2 wait state */ FLASH_SetLatency(FLASH_Latency_2); /* HCLK = SYSCLK */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* PCLK2 = HCLK */ RCC_PCLK2Config(RCC_HCLK_Div1); /* PCLK1 = HCLK/2 */ RCC_PCLK1Config(RCC_HCLK_Div2); /* ADCCLK = PCLK2/6 */ RCC_ADCCLKConfig(RCC_PCLK2_Div6); /* PLLCLK = 8MHz * 9 = 72 MHz */ RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); /* Enable PLL */ RCC_PLLCmd(ENABLE); /* Wait till PLL is ready */ while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {} /* Select PLL as system clock source */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* Wait till PLL is used as system clock source */ while (RCC_GetSYSCLKSource() != 0x08) {} }

This code, rather conveniently, uses an 8MHz external crystal so we can almost direct-port it to the blue-pill Rust code and see how we go. If you're used to the CMSIS libraries for STM32, then you won't completely recognise the above since it uses the pre-CMSIS core libraries to do its thing. Library code from 2008 and it's still good on today's STM32s providing they're in the right family :-)

A direct conversion to Rust, using Jorge's beautifully easy to work with crates made from svd2rust results in:

fn make_go_faster(rcc: &RCC, flash: &FLASH) { rcc.cr.modify(|_, w| w.hseon().enabled()); while !rcc.cr.read().hserdy().is_ready() {} flash.acr.modify(|_, w| w.prftbe().enabled()); flash.acr.modify(|_, w| w.latency().two()); rcc.cfgr.modify(|_, w| w .hpre().div1() .ppre2().div1() .ppre1().div2() // .adcpre().bits(8) .pllsrc().external() .pllxtpre().div1() .pllmul().mul9() ); rcc.cr.modify(|_, w| w.pllon().enabled()); while rcc.cr.read().pllrdy().is_unlocked() {} rcc.cfgr.modify(|_,w| w.sw().pll()); while !rcc.cfgr.read().sws().is_pll() {} }

Now, I've not put the comments in which were in the C code, because I'm being very lazy right now, but if you follow the two together you should be able to work it through. I don't have timeouts for the waits, and you'll notice a single comment there (I cannot set up the ADC prescaler because for some reason the SVD is missing any useful information and so the generated crate only carries an unsafe function (bits()) and I'm trying to steer clear of unsafe for now. Still, I don't need the ADC immediately, so I'm okay with this.

By using this function in the beginning of the init() function of the blinky example, I can easily demonstrate the clock is going faster since the LED blinks more quickly.

This function demonstrates just how simple it is to take bit-manipulation from the C code and turn it into (admittedly bad looking) Rust with relative ease and without any of the actual bit-twiddling. I love it.

Mess with time, and you get unexpected consequences

Sadly, when you mess with the clock tree on a microcontroller, you throw a lot of things out of whack. Not least, by adjusting the clock frequency up we end up adjusting the AHB, APB1, and APB2 clock frequencies. This has direct consequences for peripherals floating around on those busses. Fortunately Jorge thought of this and while the blue-pill crate hard-wires those frequencies to 8MHz, they are, at least, configurable in code in some sense.

If we apply the make_go_faster() function to the serial loopback example, it simply fails to work because now the bus which the USART1 peripheral is connected to (APB2) is going at a different speed from the expected power-on default of 8MHz. If you remember from the function, we did .hpre().div1() which set HCLK to 72MHz, then .ppre1().div2() which sets the APB1 bus clock to be HCLK divided by 2, and .ppre2().div1() which sets APB2 bus clock to be HCLK. This means that we'd need to alter src/lib.rs to reflect these changes in the clock frequences and in theory loopback would start working once more.

It'd be awkward to try and demonstrate all that to you since I only have a phone camera to hand, but if you own a blue-pill then you can clone Jorge's repo and have a go yourself and see that I'm not bluffing you.

With all this done, it'll be time to see if we can bring the USB peripheral in the STM32 online, and that will be the topic of my next post in this discovery series.

Categories: LUG Community Blogs

Debian Bits: DebConf17 starts today in Montreal

Planet HantsLUG - Sun, 06/08/2017 - 14:00

DebConf17, the 18th annual Debian Conference, is taking place in Montreal, Canada from August 6 to August 12, 2017.

Debian contributors from all over the world have come together at Collège Maisonneuve during the preceding week for DebCamp (focused on individual work and team sprints for in-person collaboration developing Debian), and the Open Day on August 5th (with presentations and workshops of interest to a wide audience).

Today the main conference starts with nearly 400 attendants and over 120 activities scheduled, including 45- and 20-minute talks and team meetings, workshops, a job fair, talks from invited speakers, as well as a variety of other events.

The full schedule at https://debconf17.debconf.org/schedule/ is updated every day, including activities planned ad-hoc by attendees during the whole conference.

If you want to engage remotely, you can follow the video streaming of the events happening in the three talk rooms: Buzz (the main auditorium), Rex, and Bo, or join the conversation about what is happening in the talk rooms: #debconf17-buzz, #debconf17-rex and #debconf17-bo, and the BoF (discussions) rooms: #debconf17-potato and #debconf17-woody (all those channels in the OFTC IRC network).

DebConf is committed to a safe and welcome environment for all participants. See the DebConf Code of Conduct and the Debian Code of Conduct for more details on this.

Debian thanks the commitment of numerous sponsors to support DebConf17, particularly our Platinum Sponsors Savoir-Faire Linux, Hewlett Packard Enterprise, and Google.

Categories: LUG Community Blogs

Debian Bits: Google Platinum Sponsor of DebConf17

Planet HantsLUG - Sat, 05/08/2017 - 21:30

We are very pleased to announce that Google has committed support to DebConf17 as a Platinum sponsor.

Google is one of the largest technology companies in the world, providing a wide range of Internet-related services and products as online advertising technologies, search, cloud computing, software, and hardware.

Google has been supporting Debian by sponsoring DebConf since more than ten years, and at gold level since DebConf12.

With this additional commitment as Platinum Sponsor for DebConf17, Google contributes to make possible our annual conference, and directly supports the progress of Debian and Free Software helping to strengthen the community that continues to collaborate on Debian projects throughout the rest of the year.

Thank you very much Google, for your support of DebConf17!

DebConf17 is starting!

Many Debian contributors are already taking advantage of DebCamp and the Open Day to work individually or in groups developing and improving Debian. DebConf17 will officially start on August 6, 2017. Visit the DebConf17 website at https://debconf17.debconf.org to know the schedule, live streaming and other details.

Categories: LUG Community Blogs

Daniel Silverstone (Kinnison): USB Device Stacks, on RTFM, part 2

Planet ALUG - Sat, 05/08/2017 - 16:08

Previously we talked about all the different kinds of descriptors which USB devices use to communicate their capability. This is important stuff because to write any useful USB device firmware we need to be able to determine how to populate our descriptors. However, having that data on the device is entirely worthless without an understanding of how it gets from the device to the host so that it can be acted upon. To understand that, let's look at the USB wire protocol.

Note, I'll again be talking mostly about USB2.0 low- and full-speed. I believe that high speed is approximately the same but with faster wires, except not quite that simple.

Down to the wire

I don't intend to talk about the actual electrical signalling, though it's not un-reasonable for you to know that USB is a pair of wires forming a differentially signalled bidirectional serial communications link. The host is responsible for managing all the framing and timing on the link, and for formatting the communications into packets.

There are a number of packet types which can appear on the USB link:

Packet type Purpose Token Packet When the host wishes to send a message to the Control endpoint to configure the device, read data IN, or write data OUT, it uses this to start the transaction. Data(0/1) Packet Following a Setup, In, or Out token, a Data packet is a transfer of data (in either direction). The 0 and 1 alternate to provide a measure of confidence against lost packets. Handshake Packet Following a data packet of some kind, the other end may ACK the packet (all was well), NAK the packet (report that the device cannot, temporarily, send/receive data, or that an interrupt endpoint isn't triggered), or STALL the bus in which case the host needs to intervene. Start of Frame Every 1ms (full-speed) the host will send a SOF packet which carries a frame number. This can be used to help keep time on very simple devices. It also divides the bus into frames within which bandwidth is allocated.

As an example, when the host wishes to perform a control transfer, the following packets are transacted in turn:

  1. Setup Token - The host addresses the device and endpoint (OUT0)
  2. Data0 Packet - The host transmits a GET_DESCRIPTOR for the device descriptor
  3. Ack Packet - The device acknowledges receipt of the request

This marks the end of the first transaction. The device decodes the GET_DESCRIPTOR request and prepares the device descriptor for transmission. The transmission occurs as the next transaction on the bus. In this example, we're assuming 8 byte maximum transmission sizes, for illustrative purposes.

  1. In Token - The host addresses the device and endpoint (IN0)
  2. Data1 Packet - The device transmits the first 8 bytes of the descriptor
  3. Ack Packet - The host acknowledges the data packet
  4. In Token - The host addresses the device and endpoint (IN0)
  5. Data0 Packet - The device transmits the remaining 4 bytes of the descriptor (padded)
  6. Ack Packet - The host acknowledges the data packet

The second transaction is now complete, and the host has all the data it needs to proceed. Finally a status transaction occurs in which:

  1. Out Token - The host addresses the device and endpoint (OUT0)
  2. Data1 Packet - The host transmits a 0 byte data packet to indicate successful completion
  3. Ack Packet - The device acknowledges the completion, indicating its own satisfaction

And thus ends the full control transaction in which the host retrieves the device descriptor.

From a high level, we need only consider the activity which occurs at the point of the acknowledgement packets. In the above example:

  1. On the first ACK the device prepares IN0 to transmit the descriptor, readying whatever low level device stack there is with a pointer to the descriptor and its length in bytes.
  2. On the second ACK the low levels are still thinking.
  3. On the third ACK the transmission from IN0 is complete and the endpoint no longer expects to transfer data.
  4. On the fourth ACK the control transaction is entirely complete.
Thinking at the low levels of the control interface

Before we can build a high level USB stack, we need to consider the activity which might occur at the lower levels. At the low levels, particularly of the device control interface, work has to be done at each and every packet. The hardware likely deals with the token packet for us, leaving the data packets for us to process, and the resultant handshake packets will be likely handled by the hardware in response to our processing the data packets.

Since every control transaction is initiated by a setup token, let's look at the setup requests which can come our way...

Setup Packet (Data) Format Field Name Byte start Byte length Encoding Meaning bmRequestType 0 1 Bitmap Describes the kind of request, and the target of it. See below. bRequest 1 1 Code The request code itself, meanings of the rest of the fields vary by bRequest wValue 2 2 Number A 16 bit value whose meaning varies by request type wIndex 4 2 Number A 16 bit value whose meaning varies by request type but typically encodes an interface number or endpoint. wLength 6 2 Number A 16 bit value indicating the length of the transfer to come.

Since bRequest is essentially a switch against which multiple kinds of setup packet are selected between, here's the meanings of a few...

GET_DESCRIPTOR (Device) setup packet Field Name Value Meaning bmRequestType 0x08 Data direction is IN (from device to host), recipient is the device bRequest 0x06 GET_DESCRIPTOR (in this instance, the device descriptor is requested) wValue 0x0001 This means the device descriptor wIndex 0x0000 Irrelevant, there's only 1 device descriptor anyway wLength 12 This is the length of a device descriptor (12 bytes) SET_ADDRESS to set a device's USB address Field Name Value Meaning bmRequestType 0x00 Data direction is OUT (from host to device), recipient is the device bRequest 0x05 SET_ADDRESS (Set the device's USB address) wValue 0x00nn The address for the device to adopt (max 127) wIndex 0x0000 Irrelevant for address setting wLength 0 There's no data transfer expected for this setup operation

Most hardware blocks will implement an interrupt at the point that the Data packet following the Setup packet has been receive. This is typically called receiving a 'Setup' packet and then it's up to the device stack low levels to determine what to do and dispatch a handler. Otherwise an interrupt will fire for the IN or OUT tokens and if the endpoint is zero, the low level stack will handle it once more.

One final thing worth noting about SET_ADDRESS is that it doesn't take effect until the completion of the zero-length "status" transaction following the setup transaction. As such, the status request from the host will still be sent to address zero (the default for new devices).

A very basic early "packet trace"

This is an example, and is not guaranteed to be the packet sequence in all cases. It's a good indication of the relative complexity involved in getting a fresh USB device onto the bus though...

When a device first attaches to the bus, the bus is in RESET state and so the first event a device sees is a RESET which causes it to set its address to zero, clear any endpoints, clear the configuration, and become ready for control transfers. Shortly after this, the device will become suspended.

Next, the host kicks in and sends a port reset of around 30ms. After this, the host is ready to interrogate the device.

The host sends a GET_DESCRIPTOR to the device, whose address at this point is zero. Using the information it receives from this, it can set up the host-side memory buffers since the device descriptor contains the maximum transfer size which the device supports.

The host is now ready to actually 'address' the device, and so it sends another reset to the device, again around 30ms in length.

The host sends a SET_ADDRESS control request to the device, telling it that its new address is nn. Once the acknowledgement has been sent from the host for the zero-data status update from the device, the device sets its internal address to the value supplied in the request. From now on, the device shall respond only to requests to nn rather than to zero.

At this point, the host will begin interrogating further descriptors, looking at the configuration descriptors and the strings, to build its host-side representation of the device. These will be GET_DESCRIPTOR and GET_STRING_DESCRIPTOR requests and may continue for some time.

Once the host has satisfied itself that it knows everything it needs to about the device, it will issue a SET_CONFIGURATION request which basically starts everything up in the device. Once the configuration is set, interrupt endpoints will be polled, bulk traffic will be transferred, Isochronous streams begin to run, etc.

Okay, but how do we make this concrete?

So far, everything we've spoken about has been fairly abstract, or at least "soft". But to transfer data over USB does require some hardware. (Okay, okay, we could do it all virtualised, but there's no fun in that). The hardware I'm going to be using for the duration of this series is the STM32 on the blue-pill development board. This is a very simple development board which does (in theory at least) support USB device mode.

If we view the schematic for the blue-pill, we can see a very "lightweight" USB interface which has a pullup resistor for D+. This is the way that a device signals to the host that it is present, and that it wants to speak at full-speed. If the pullup were on D- then it would be a low-speed device. High speed devices need a little more complexity which I'm not going to go into for today.

The USB lines connect to pins PA11 and PA12 which are the USB pins on the STM32 on the board. Since USB is quite finicky, the STM32 doesn't let you remap that function elsewhere, so this is all looking quite good for us so far.

The specific STM32 on the blue-pill is the STM32F103C8T6. By viewing its product page on ST's website we can find the reference manual for the part. Jumping to section 23 we learn that this STM32 supports full-speed USB2.0 which is convenient given the past article and a half. We also learn it supports up to eight endpoints active at any one time, and offers double-buffering for our bulk and isochronous transfers. It has some internal memory for packet buffering, so it won't use our RAM bandwidth while performing transfers, which is lovely.

I'm not going to distill the rest of that section here, because there's a large amount of data which explains how the USB macrocell operates. However useful things to note are:

  • How IN OUT and SETUP transfers work.
  • How the endpoint buffer memory is configured.
  • That all bus-powered devices MUST respond to suspend/resume properly
  • That the hardware will prioritise endpoint interrupts for us so that we only need deal with the most pressing item at any given time.
  • There is an 'Enable Function' bit in the address register which must be set or we won't see any transactions at all.
  • How the endpoint registers signal events to the device firmware.

Next time, we're going to begin the process of writing a very hacky setup routine to try and initialise the USB device macrocell so that we can see incoming transactions through the ITM. It should be quite exciting, but given how complex this will be for me to learn, it might be a little while before it comes through.

Categories: LUG Community Blogs

Debian Bits: DebConf17 Open Day

Planet HantsLUG - Sat, 05/08/2017 - 14:00

Today, the day preceeding the official start of the annual Debian Conference, is the Open Day at DebConf17, at Collège Maisonneuve in Montreal (Canada).

This day is open to the public with events of interest to a wide audience.

The schedule of today's events include, among others:

  • A Newbie's Newbie Guide to Debian
  • Ask Anything About Debian
  • Debian Packaging 101
  • Debian InstallFest
  • Presentations or workshops related to free software projects and local organizations.

Everyone is welcome to attend! It is a great possibility for interested users to meet our community and for Debian to widen our community.

See the full schedule for today's events at https://debconf17.debconf.org/schedule/open-day/.

If you want to engage remotely, you can watch the video streaming of the Open Day events happening in the "Rex" room, or join the conversation in the channels #debconf17-rex, #debconf17-potato and #debconf17-woody in the OFTC IRC network.

DebConf is committed to a safe and welcome environment for all participants. See the DebConf Code of Conduct and the Debian Code of Conduct for more details on this.

Debian thanks the commitment of numerous sponsors to support DebConf17, particularly our Platinum Sponsors Savoir-Faire Linux, Hewlett Packard Enterprise, and Google.

Categories: LUG Community Blogs

Daniel Silverstone (Kinnison): USB Device Stacks, on RTFM

Planet ALUG - Fri, 04/08/2017 - 16:05

I have been spending time with Jorge Aparicio's RTFM for Cortex M3 framework for writing Rust to target Cortex-M3 devices from Arm (and particularly the STM32F103 from ST Microelectronics). Jorge's work in this area has been of interest to me ever since I discovered him working on this stuff a while ago. I am very tempted by the idea of being able to implement code for the STM32 with the guarantees of Rust and the language features which I have come to love such as the trait system.

I have been thinking to myself that, while I admire and appreciate the work done on the GNUK, I would like to, personally, have a go at implementing some kind of security token on an STM32 as a USB device. And with the advent of the RTFM for M3 work, and Jorge's magical tooling to make it easier to access and control the registers on an M3 microcontroller, I figured it'd be super-nice to do this in Rust, with all the advantages that entails in terms of isolating unsafe behaviour and generally having the potential to be more easily verified as not misbehaving.

To do this though, means that I need a USB device stack which will work in the RTFM framework. Sadly it seems that, thus-far, only Jorge has been working on drivers for any of the M3 devices his framework supports. And one person can only do so much. So, in my infinite madness, I decided I should investigate the complexity of writing a USB device stack in Rust for the RTFM/M3 framework. (Why I thought this was a good idea is lost to the mists of late night Googling, but hey, it might make a good talk at the next conference I go to). As such, this blog post, and further ones along these lines, will serve as a partial tour of what I'm up to, and a partial aide-memoir for me about learning USB. If I get something horribly wrong, please DO contact me to correct me, otherwise I'll just continue to be wrong. If I've simplified something but it's still strictly correct, just let me know if it's an oversimplification since in a lot of cases there's no point in me putting the full details into a blog posting. I will mostly be considering USB2.0 protocol details but only really for low and full speed devices. (The hardware I'm targetting does low-speed and full-speed, but not high-speed. Though some similar HW does high-speed too, I don't have any to hand right now)

A brief introduction to USB

In order to go much further, I needed a grounding in USB. It's a multi-layer protocol as you might expect, though we can probably ignore the actual electrical layer since any device we might hope to support will have to have a hardware block to deal with that. We will however need to consider the packet layer (since that will inform how the hardware block is implemented and thus its interface) and then the higher level protocols on top.

USB is a deliberately asymmetric protocol. Devices are meant to be significantly easier to implement, both in terms of hardware and software, as compared with hosts. As such, despite some STM32s having OTG ports, I have no intention of supporting host mode at this time.

USB is arranged into a set of busses which are, at least in the USB1.1 case, broadcast domains. As such, each device has an address assigned to it by the host during an early phase called 'configuration'. Once the address is assigned, the device is expected to only ever respond to messages addressed to it. Note that since everything is asymmetric in USB, the device can't send messages on its own, but has to be asked for them by the host, and as such the addressing is always from host toward device.

USB devices then expose a number of endpoints through which communication can flow IN to the host or OUT to the device. Endpoints are not bidirectional, but the in and out endpoints do overlap in numbering. There is a special pair of endpoints, IN0 and OUT0 which, between them, form what I will call the device control endpoints. The device control endpoints are important since every USB device MUST implement them, and there are a number of well defined messages which pass over them to control the USB device. In theory a bare minimum USB device would implement only the device control endpoints.

Configurations, and Classes, and Interfaces, Oh My!

In order for the host to understand what the USB device is, and what it is capable of, part of the device control endpoints' responsibility is to provide a set of descriptors which describe the device. These descriptors form a heirarchy and are then glommed together into a big lump of data which the host can download from the device in order to decide what it is and how to use it. Because of various historical reasons, where a multi-byte value is used, they are defined to be little-endian, though there are some BCD fields. Descriptors always start with a length byte and a type byte because that way the host can parse/skip as necessary, with ease.

The first descriptor is the device descriptor, is a big one, and looks like this:

Device Descriptor Field Name Byte start Byte length Encoding Meaning bLength 0 1 Number Size of the descriptor in bytes (18) bDescriptorType 1 1 Constant Device Descriptor (0x01) bcdUSB 2 2 BCD USB spec version compiled with bDeviceClass 4 1 Class Code, assigned by USB org (0 means "Look at interface descriptors", common value is 2 for CDC) bDeviceSubClass 5 1 SubClass Code, assigned by USB org (usually 0) bDeviceProtocol 6 1 Protocol Code, assigned by USB org (usually 0) bMaxPacketSize 7 1 Number Max packet size for IN0/OUT0 (Valid are 8, 16, 32, 64) idVendor 8 2 ID 16bit Vendor ID (Assigned by USB org) idProduct 10 2 ID 16bit Product ID (Assigned by manufacturer) bcdDevice 12 2 BCD Device version number (same encoding as bcdUSB) iManufacturer 14 1 Index String index of manufacturer name (0 if unavailable) iProduct 15 1 Index String index of product name (0 if unavailable) iSerialNumber 16 1 Index String index of device serial number (0 if unavailable) bNumConfigurations 17 1 Number Count of configurations the device has.

This looks quite complex, but breaks down into a relatively simple two halves. The first eight bytes carries everything necessary for the host to be able to configure itself and the device control endpoints properly in order to communicate effectively. Since eight bytes is the bare minimum a device must be able to transmit in one go, the host can guarantee to get those, and they tell it what kind of device it is, what USB protocol it supports, and what the maximum transfer size is for its device control endpoints.

The encoding of the bcdUSB and bcdDevice fields is interesting too. It is of the form 0xMMmm where MM is the major number, mm the minor. So USB2.0 is encoded as 0x0200, USB1.1 as 0x0110 etc. If the device version is 17.36 then that'd be 0x1736.

Other fields of note are bDeviceClass which can be 0 meaning that interfaces will specify their classes, and idVendor/idProduct which between them form the primary way for the specific USB device to be identified. The Index fields are indices into a string table which we'll look at later. For now it's enough to know that wherever a string index is needed, 0 can be provided to mean "no string here".

The last field is bNumConfigurations and this indicates the number of ways in which this device might function. A USB device can provide any number of these configurations, though typically only one is provided. If the host wishes to switch between configurations then it will have to effectively entirely quiesce and reset the device.

The next kind of descriptor is the configuration descriptor. This one is much shorter, but starts with the same two fields:

Configuration Descriptor Field Name Byte start Byte length Encoding Meaning bLength 0 1 Number Size of the descriptor in bytes (9) bDescriptorType 1 1 Constant Configuration Descriptor (0x02) wTotalLength 2 2 Number Size of the configuration in bytes, in total bNumInterfaces 4 1 Number The number of interfaces in this configuration bConfigurationValue 5 1 Number The value to use to select this configuration iConfiguration 6 1 Index The name of this configuration (0 for unavailable) bmAttributes 7 1 Bitmap Attributes field (see below) bMaxPower 8 1 Number Maximum bus power this configuration will draw (in 2mA increments)

An important field to consider here is the bmAttributes field which tells the host some useful information. Bit 7 must be set, bit 6 is set if the device would be self-powered in this configuration, bit 5 indicates that the device would like to be able to wake the host from sleep mode, and bits 4 to 0 must be unset.

The bMaxPower field is interesting because it encodes the power draw of the device (when set to this configuration). USB allows for up to 100mA of draw per device when it isn't yet configured, and up to 500mA when configured. The value may be used to decide if it's sensible to configure a device if the host is in a low power situation. Typically this field will be set to 50 to indicate the nominal 100mA is fine, or 250 to request the full 500mA.

Finally, the wTotalLength field is interesting because it tells the host the total length of this configuration, including all the interface and endpoint descriptors which make it up. With this field, the host can allocate enough RAM to fetch the entire configuration descriptor block at once, simplifying matters dramatically for it.

Each configuration has one or more interfaces. The interfaces group some endpoints together into a logical function. For example a configuration for a multifunction scanner/fax/printer might have an interface for the scanner function, one for the fax, and one for the printer. Endpoints are not shared among interfaces, so when building this table, be careful.

Next, logically, come the interface descriptors:

Interface Descriptor Field Name Byte start Byte length Encoding Meaning bLength 0 1 Number Size of the descriptor in bytes (9) bDescriptorType 1 1 Constant Interface Descriptor (0x04) bInterfaceNumber 2 1 Number The number of the interface bAlternateSetting 3 1 Number The interface alternate index bNumEndpoints 4 1 Number The number of endpoints in this interface bInterfaceClass 5 1 Class The interface class (USB Org defined) bInterfaceSubClass 6 1 SubClass The interface subclass (USB Org defined) bInterfaceProtocol 7 1 Protocol The interface protocol (USB Org defined) iInterface 8 1 Index The name of the interface (or 0 if not provided)

The important values here are the class/subclass/protocol fields which provide a lot of information to the host about what the interface is. If the class is a USB Org defined one (e.g. 0x02 for Communications Device Class) then the host may already have drivers designed to work with the interface meaning that the device manufacturer doesn't have to provide host drivers.

The bInterfaceNumber is used by the host to indicate this interface when sending messages, and the bAlternateSetting is a way to vary interfaces. Two interfaces with the came bInterfaceNumber but different bAlternateSettings can be switched between (like configurations, but) without resetting the device.

Hopefully the rest of this descriptor is self-evident by now.

The next descriptor kind is endpoint descriptors:

Endpoint Descriptor Field Name Byte start Byte length Encoding Meaning bLength 0 1 Number Size of the descriptor in bytes (7) bDescriptorType 1 1 Constant Endpoint Descriptor (0x05) bEndpointAddress 2 1 Endpoint Endpoint address (see below) bmAttributes 3 1 Bitmap Endpoint attributes (see below) wMaxPacketSize 4 2 Number Maximum packet size this endpoint can send/receive bInterval 6 1 Number Interval for polling endpoint (in frames)

The bEndpointAddress is a 4 bit endpoint number (so there're 16 endpoint indices) and a bit to indicate IN vs. OUT. Bit 7 is the direction marker and bits 3 to 0 are the endpoint number. This means there are 32 endpoints in total, 16 in each direction, 2 of which are reserved (IN0 and OUT0) giving 30 endpoints available for interfaces to use in any given configuration. The bmAttributes bitmap covers the transfer type of the endpoint (more below), and the bInterval is an interval measured in frames (1ms for low or full speed, 125µs in high speed). bInterval is only valid for some endpoint types.

The final descriptor kind is for the strings which we've seen indices for throughout the above. String descriptors have two forms:

String Descriptor (index zero) Field Name Byte start Byte length Encoding Meaning bLength 0 1 Number Size of the descriptor in bytes (variable) bDescriptorType 1 1 Constant String Descriptor (0x03) wLangID[0] 2 2 Number Language code zero (e.g. 0x0409 for en_US) wLangID[n] 4.. 2 Number Language code n ...

This form (for descriptor 0) is that of a series of language IDs supported by the device. The device may support any number of languages. When the host requests a string descriptor, it will supply both the index of the string and also the language id it desires (from the list available in string descriptor zero). The host can tell how many language IDs are available simply by dividing bLength by 2 and subtracting 1 for the two header bytes.

And for string descriptors of an index greater than zero:

String Descriptor (index greater than zero) Field Name Byte start Byte length Encoding Meaning bLength 0 1 Number Size of the descriptor in bytes (variable) bDescriptorType 1 1 Constant String Descriptor (0x03) bString 2.. .. Unicode The string, in "unicode" format

This second form of the string descriptor is simply the the string is in what the USB spec calls 'Unicode' format which is, as of 2005, defined to be UTF16-LE without a BOM or terminator.

Since string descriptors are of a variable length, the host must request strings in two transactions. First a request for 2 bytes is sent, retrieving the bLength and bDescriptorType fields which can be checked and memory allocated. Then a request for bLength bytes can be sent to retrieve the entire string descriptor.

Putting that all together

Phew, this is getting to be quite a long posting, so I'm going to leave this here and in my next post I'll talk about how the host and device pass packets to get all that information to the host, and how it gets used.

Categories: LUG Community Blogs

Daniel Silverstone (Kinnison): Gitano 1.1

Planet ALUG - Thu, 03/08/2017 - 16:34

Today marks the release of Gitano 1.1. Richard(s) and I have spent quite a lot of time and effort on this release, and there's plenty of good stuff in it. We also released new versions of Lace, Supple, Luxio, and Gall to go alongside it, with bugfixes and improvements.

At this point, I intend to take a short break from Gitano to investigate some Rust-on-STM32 stuff, and then perhaps do some NetSurf work too.

Categories: LUG Community Blogs

Andy Smith: A slightly more realistic look at lvmcache

Planet HantsLUG - Thu, 03/08/2017 - 13:59
Recap And then…

I decided to perform some slightly more realistic benchmarks against lvmcache.

The problem with the initial benchmark was that it only covered 4GiB of data with a 4GiB cache device. Naturally once lvmcache was working correctly its performance was awesome – the entire dataset was in the cache. But clearly if you have enough fast block device available to fit all your data then you don’t need to cache it at all and may as well just use the fast device directly.

I decided to perform some fio tests with varying data sizes, some of which were larger than the cache device.

Test methodology

Once again I used a Zipf distribution with a factor of 1.2, which should have caused about 90% of the hits to come from just 10% of the data. I kept the cache device at 4GiB but varied the data size. The following data sizes were tested:

  • 1GiB
  • 2GiB
  • 4GiB
  • 8GiB
  • 16GiB
  • 32GiB
  • 48GiB

With the 48GiB test I expected to see lvmcache struggling, as the hot 10% (~4.8GiB) would no longer fit within the 4GiB cache device.

A similar fio job spec to those from the earlier articles was used:

[cachesize-1g] size=512m ioengine=libaio direct=1 iodepth=8 numjobs=2 readwrite=randread random_distribution=zipf:1.2 bs=4k unlink=1 runtime=30m time_based=1 per_job_logs=1 log_avg_msec=500 write_iops_log=/var/tmp/fio-${FIOTEST}

…the only difference being that several different job files were used each with a different size= directive. Note that as there are two jobs, the size= is half the desired total data size: each job lays out a data file of the specified size.

For each data size I took care to fill the cache with data first before doing a test run, as unreproducible performance is still seen against a completely empty cache device. This produced IOPS logs and a completion latency histogram. Test were also run against SSD and HDD to provide baseline figures.

Results IOPS graphs All-in-one

Immediately we can see that for data sizes 4GiB and below performance converges quite quickly to near-SSD levels. That is very much what we would expect when the cache device is 4GiB, so big enough to completely cache everything.

Let’s just have a look at the lower-performing configurations.

Low-end performers

For 8, 16 and 32GiB data sizes performance clearly gets progressively worse, but it is still much better than baseline HDD. The 10% of hot data still fits within the cache device, so plenty of acceleration is still happening.

For the 48GiB data size it is a little bit of a different story. Performance is still better (on average) than baseline HDD, but there are periodic dips back down to roughly HDD figures. This is because not all of the 10% hot data fits into the cache device any more. Cache misses cause reads from HDD and consequently end up with HDD levels of performance for those reads.

The results no longer look quite so impressive, with even the 8GiB data set achieving only a few thousand IOPS on average. Are things as bad as they seem? Well no, I don’t think they are, and to see why we will have to look at the completion latency histograms.

Completion latency histograms

The above graphs are generated by fitting a Bezier curve to a scatter of data points each of which represents a 500ms average of IOPS achieved. The problem there is the word average.

It’s important to understand what effect averaging the figures gives. We’ve already seen that HDDs are really slow. Even if only a few percent of IOs end up missing cache and going to HDD, the massive latency of those requests will pull the average for the whole 500ms window way down.

Presumably we have a cache because we suspect we have hot spots of data, and we’ve been trying to evaluate that by doing most of the reads from only 10% of the data. Do we care what the average performance is then? Well it’s a useful metric but it’s not going to say much about the performance of reads from the hot data.

The histogram of completion latencies can be more useful. This shows how long it took between issuing the IO and completing the read for a certain percentage of issued IOs. Below I have focused on the 50% to 99% latency buckets, with the times for each bucket averaged between the two jobs. In the interests of being able to see anything at all I’ve had to double the height of the graph and still cut off the y axis for the three worst performers.

A couple of observations:

  • Somewhere between 70% and 80% of IOs complete with a latency that’s so close to SSD performance as to be near-indistinguishable, no matter what the data size. So what I think I am proving is that:

    you can cache a 48GiB slow backing device with 4GiB of fast SSD and if you have 10% hot data then you can expect it to be served up at near-SSD latencies 70%–80% of the time. If your hot spots are larger (not so hot) then you won’t achieve that. If your fast device is larger than 1/12th the backing device then you should do better than 70%–80%.

  • If the cache were perfect then we should expect the 90th percentile to be near SSD performance even for the 32GiB data set, as the 10% hot spot of ~3.2GiB fits inside the 4GiB cache. For whatever reason this is not achieved, but for that data size the 90th percentile latency is still about half that of HDD.
  • When the backing device is many times larger (32GiB+) than the cache device, the 99th percentile latencies can be slightly worse than for baseline HDD.

    I hesitate to suggest there is a problem here as there are going to be very few samples in the top 1%, so it could just be showing close to HDD performance.

Conclusion

Assuming you are okay with using a 4.12..x kernel, and assuming you are already comfortable using LVM, then at the moment it looks fairly harmless to deploy lvmcache.

Getting a decent performance boost out of it though will require you to check that your data really does have hot spots and size your cache appropriately.

Measuring your existing workload with something like blktrace is probably advisable, and these days you can feed the output of blktrace back into fio to see what performance might be like in a difference configuration.

Full test output

You probably want to stop reading here unless the complete output of all the fio runs is of interest to you.

Baseline SSD $ cd /srv/ssd/fio && FIOTEST=ssd-1g fio ~/cachesize-1g.fio cachesize-1g: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8 ... fio-2.16 Starting 2 processes cachesize-1g: Laying out IO file(s) (1 file(s) / 512MB) cachesize-1g: Laying out IO file(s) (1 file(s) / 512MB) Jobs: 2 (f=2): [r(2)] [100.0% done] [385.7MB/0KB/0KB /s] [98.8K/0/0 iops] [eta 00m:00s] cachesize-1g: (groupid=0, jobs=1): err= 0: pid=15206: Thu Aug 3 03:59:51 2017 read : io=346130MB, bw=196910KB/s, iops=49227, runt=1800001msec slat (usec): min=0, max=4188, avg= 4.76, stdev= 4.10 clat (usec): min=17, max=7093, avg=155.55, stdev=59.28 lat (usec): min=91, max=7098, avg=160.77, stdev=59.32 clat percentiles (usec): | 1.00th=[ 101], 5.00th=[ 108], 10.00th=[ 112], 20.00th=[ 119], | 30.00th=[ 124], 40.00th=[ 131], 50.00th=[ 137], 60.00th=[ 147], | 70.00th=[ 159], 80.00th=[ 181], 90.00th=[ 225], 95.00th=[ 274], | 99.00th=[ 366], 99.50th=[ 402], 99.90th=[ 474], 99.95th=[ 506], | 99.99th=[ 924] lat (usec) : 20=0.01%, 50=0.01%, 100=0.57%, 250=92.21%, 500=7.16% lat (usec) : 750=0.04%, 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01% cpu : usr=14.54%, sys=42.95%, ctx=50708834, majf=0, minf=15 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=88609406/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 cachesize-1g: (groupid=0, jobs=1): err= 0: pid=15207: Thu Aug 3 03:59:51 2017 read : io=346960MB, bw=197381KB/s, iops=49345, runt=1800001msec slat (usec): min=0, max=4180, avg= 4.76, stdev= 3.93 clat (usec): min=16, max=7097, avg=155.16, stdev=59.32 lat (usec): min=60, max=7101, avg=160.38, stdev=59.36 clat percentiles (usec): | 1.00th=[ 101], 5.00th=[ 108], 10.00th=[ 113], 20.00th=[ 119], | 30.00th=[ 124], 40.00th=[ 131], 50.00th=[ 137], 60.00th=[ 145], | 70.00th=[ 157], 80.00th=[ 179], 90.00th=[ 225], 95.00th=[ 274], | 99.00th=[ 370], 99.50th=[ 406], 99.90th=[ 474], 99.95th=[ 506], | 99.99th=[ 892] lat (usec) : 20=0.01%, 50=0.01%, 100=0.59%, 250=92.13%, 500=7.22% lat (usec) : 750=0.05%, 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01% cpu : usr=14.75%, sys=43.14%, ctx=50816422, majf=0, minf=14 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=88821698/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 Run status group 0 (all jobs): READ: io=693090MB, aggrb=394291KB/s, minb=196909KB/s, maxb=197381KB/s, mint=1800001msec, maxt=1800001msec Disk stats (read/write): xvdf: ios=177420039/9, merge=0/6, ticks=27109524/0, in_queue=27169920, util=100.00% Baseline HDD $ cd /srv/slow/fio && FIOTEST=hdd-1g fio ~/cachesize-1g.fio cachesize-1g: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8 ... fio-2.16 Starting 2 processes cachesize-1g: Laying out IO file(s) (1 file(s) / 512MB) cachesize-1g: Laying out IO file(s) (1 file(s) / 512MB) Jobs: 2 (f=2): [r(2)] [100.0% done] [2650KB/0KB/0KB /s] [662/0/0 iops] [eta 00m:00s] cachesize-1g: (groupid=0, jobs=1): err= 0: pid=18951: Thu Aug 3 04:30:08 2017 read : io=2307.8MB, bw=1312.5KB/s, iops=328, runt=1800099msec slat (usec): min=0, max=101, avg=14.31, stdev= 9.09 clat (usec): min=58, max=943511, avg=24362.98, stdev=47600.55 lat (usec): min=63, max=943517, avg=24378.15, stdev=47600.62 clat percentiles (usec): | 1.00th=[ 71], 5.00th=[ 82], 10.00th=[ 96], 20.00th=[ 127], | 30.00th=[ 181], 40.00th=[ 596], 50.00th=[ 1432], 60.00th=[ 9152], | 70.00th=[21632], 80.00th=[38656], 90.00th=[73216], 95.00th=[115200], | 99.00th=[228352], 99.50th=[280576], 99.90th=[415744], 99.95th=[468992], | 99.99th=[593920] lat (usec) : 100=11.17%, 250=23.28%, 500=4.34%, 750=2.55%, 1000=2.09% lat (msec) : 2=8.86%, 4=1.99%, 10=6.48%, 20=8.26%, 50=15.33% lat (msec) : 100=9.26%, 250=5.65%, 500=0.72%, 750=0.03%, 1000=0.01% cpu : usr=0.30%, sys=0.85%, ctx=572788, majf=0, minf=17 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=590611/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 cachesize-1g: (groupid=0, jobs=1): err= 0: pid=18952: Thu Aug 3 04:30:08 2017 read : io=2233.4MB, bw=1270.5KB/s, iops=317, runt=1800071msec slat (usec): min=0, max=113, avg=14.63, stdev= 9.18 clat (usec): min=56, max=1153.7K, avg=25167.62, stdev=48500.18 lat (usec): min=64, max=1153.8K, avg=25183.12, stdev=48500.29 clat percentiles (usec): | 1.00th=[ 72], 5.00th=[ 84], 10.00th=[ 99], 20.00th=[ 135], | 30.00th=[ 199], 40.00th=[ 892], 50.00th=[ 2640], 60.00th=[12224], | 70.00th=[21888], 80.00th=[39168], 90.00th=[74240], 95.00th=[117248], | 99.00th=[234496], 99.50th=[288768], 99.90th=[428032], 99.95th=[485376], | 99.99th=[602112] lat (usec) : 100=10.22%, 250=22.53%, 500=4.15%, 750=2.20%, 1000=1.83% lat (msec) : 2=8.43%, 4=1.66%, 10=6.40%, 20=11.41%, 50=15.37% lat (msec) : 100=9.26%, 250=5.69%, 500=0.79%, 750=0.04%, 1000=0.01% lat (msec) : 2000=0.01% cpu : usr=0.32%, sys=0.82%, ctx=551097, majf=0, minf=16 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=571725/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 Run status group 0 (all jobs): READ: io=4540.4MB, aggrb=2582KB/s, minb=1270KB/s, maxb=1312KB/s, mint=1800071msec, maxt=1800099msec Disk stats (read/write): xvde: ios=1162334/4, merge=0/1, ticks=28774452/692, in_queue=28775512, util=100.00% 1GiB data $ (cd /srv/cache/fio && FIOTEST=cachesize-1g-full fio ~/cachesize-1g.fio) cachesize-1g: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8 ... fio-2.16 Starting 2 processes cachesize-1g: Laying out IO file(s) (1 file(s) / 512MB) cachesize-1g: Laying out IO file(s) (1 file(s) / 512MB) Jobs: 2 (f=2): [r(2)] [100.0% done] [381.4MB/0KB/0KB /s] [97.7K/0/0 iops] [eta 00m:00s] cachesize-1g: (groupid=0, jobs=1): err= 0: pid=31905: Thu Aug 3 01:50:57 2017 read : io=340715MB, bw=193829KB/s, iops=48457, runt=1800001msec slat (usec): min=0, max=4500, avg= 7.09, stdev= 4.48 clat (usec): min=27, max=7408, avg=155.45, stdev=48.00 lat (usec): min=94, max=7415, avg=162.99, stdev=48.04 clat percentiles (usec): | 1.00th=[ 104], 5.00th=[ 112], 10.00th=[ 118], 20.00th=[ 124], | 30.00th=[ 131], 40.00th=[ 137], 50.00th=[ 143], 60.00th=[ 151], | 70.00th=[ 163], 80.00th=[ 179], 90.00th=[ 211], 95.00th=[ 245], | 99.00th=[ 322], 99.50th=[ 350], 99.90th=[ 414], 99.95th=[ 450], | 99.99th=[ 644] lat (usec) : 50=0.01%, 100=0.21%, 250=95.28%, 500=4.49%, 750=0.01% lat (usec) : 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01% cpu : usr=14.89%, sys=52.95%, ctx=39879588, majf=0, minf=18 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=87222941/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 cachesize-1g: (groupid=0, jobs=1): err= 0: pid=31906: Thu Aug 3 01:50:57 2017 read : io=347850MB, bw=197888KB/s, iops=49472, runt=1800001msec slat (usec): min=0, max=4535, avg= 7.06, stdev= 4.60 clat (usec): min=25, max=7437, avg=152.11, stdev=47.15 lat (usec): min=62, max=7443, avg=159.62, stdev=47.23 clat percentiles (usec): | 1.00th=[ 104], 5.00th=[ 111], 10.00th=[ 116], 20.00th=[ 123], | 30.00th=[ 129], 40.00th=[ 133], 50.00th=[ 139], 60.00th=[ 147], | 70.00th=[ 157], 80.00th=[ 175], 90.00th=[ 203], 95.00th=[ 239], | 99.00th=[ 314], 99.50th=[ 342], 99.90th=[ 410], 99.95th=[ 446], | 99.99th=[ 724] lat (usec) : 50=0.01%, 100=0.26%, 250=95.76%, 500=3.97%, 750=0.01% lat (usec) : 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01% cpu : usr=15.41%, sys=53.33%, ctx=39452819, majf=0, minf=17 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=89049700/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 Run status group 0 (all jobs): READ: io=688565MB, aggrb=391716KB/s, minb=193828KB/s, maxb=197888KB/s, mint=1800001msec, maxt=1800001msec Disk stats (read/write): dm-2: ios=176255221/16, merge=0/0, ticks=26526400/152, in_queue=26612320, util=100.00%, aggrios=58763012/5471, aggrmerge=0/0, aggrticks=8781482/98230, aggrin_queue=8904092, aggrutil=100.00% dm-1: ios=0/0, merge=0/0, ticks=0/0, in_queue=0, util=0.00%, aggrios=176289036/11, aggrmerge=0/5, aggrticks=26394628/0, aggrin_queue=26430140, aggrutil=100.00% xvdc: ios=176289036/11, merge=0/5, ticks=26394628/0, in_queue=26430140, util=100.00% dm-0: ios=176289036/16, merge=0/0, ticks=26344448/0, in_queue=26417584, util=100.00% dm-3: ios=0/16397, merge=0/0, ticks=0/294692, in_queue=294692, util=1.07%, aggrios=0/16397, aggrmerge=0/0, aggrticks=0/294580, aggrin_queue=294580, aggrutil=1.07% xvdd: ios=0/16397, merge=0/0, ticks=0/294580, in_queue=294580, util=1.07% 2GiB data $ (cd /srv/cache/fio && FIOTEST=cachesize-2g-full fio ~/cachesize-2g.fio) cachesize-2g: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8 ... fio-2.16 Starting 2 processes cachesize-2g: Laying out IO file(s) (1 file(s) / 1024MB) cachesize-2g: Laying out IO file(s) (1 file(s) / 1024MB) Jobs: 2 (f=2): [r(2)] [100.0% done] [382.1MB/0KB/0KB /s] [98.4K/0/0 iops] [eta 00m:00s] cachesize-2g: (groupid=0, jobs=1): err= 0: pid=3134: Wed Aug 2 17:32:04 2017 read : io=343242MB, bw=195266KB/s, iops=48816, runt=1800001msec slat (usec): min=0, max=4825, avg= 6.98, stdev= 4.42 clat (usec): min=26, max=6629, avg=154.48, stdev=47.36 lat (usec): min=93, max=6634, avg=161.93, stdev=47.41 clat percentiles (usec): | 1.00th=[ 103], 5.00th=[ 110], 10.00th=[ 115], 20.00th=[ 123], | 30.00th=[ 129], 40.00th=[ 137], 50.00th=[ 143], 60.00th=[ 151], | 70.00th=[ 163], 80.00th=[ 179], 90.00th=[ 207], 95.00th=[ 237], | 99.00th=[ 314], 99.50th=[ 342], 99.90th=[ 418], 99.95th=[ 458], | 99.99th=[ 1020] lat (usec) : 50=0.01%, 100=0.32%, 250=95.80%, 500=3.84%, 750=0.02% lat (usec) : 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01% cpu : usr=14.32%, sys=52.25%, ctx=39483832, majf=0, minf=16 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=87869839/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 cachesize-2g: (groupid=0, jobs=1): err= 0: pid=3135: Wed Aug 2 17:32:04 2017 read : io=338592MB, bw=192621KB/s, iops=48155, runt=1800001msec slat (usec): min=0, max=4485, avg= 7.00, stdev= 4.45 clat (usec): min=16, max=365626, avg=156.69, stdev=493.84 lat (usec): min=66, max=365646, avg=164.17, stdev=493.95 clat percentiles (usec): | 1.00th=[ 102], 5.00th=[ 109], 10.00th=[ 114], 20.00th=[ 122], | 30.00th=[ 127], 40.00th=[ 133], 50.00th=[ 141], 60.00th=[ 149], | 70.00th=[ 161], 80.00th=[ 177], 90.00th=[ 205], 95.00th=[ 241], | 99.00th=[ 318], 99.50th=[ 346], 99.90th=[ 426], 99.95th=[ 474], | 99.99th=[12352] lat (usec) : 20=0.01%, 50=0.01%, 100=0.40%, 250=95.46%, 500=4.10% lat (usec) : 750=0.01%, 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01% lat (msec) : 100=0.01%, 250=0.01%, 500=0.01% cpu : usr=14.08%, sys=51.79%, ctx=38995321, majf=0, minf=15 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=86679580/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 Run status group 0 (all jobs): READ: io=681834MB, aggrb=387887KB/s, minb=192621KB/s, maxb=195266KB/s, mint=1800001msec, maxt=1800001msec Disk stats (read/write): dm-2: ios=174542882/20, merge=0/0, ticks=26569204/1076, in_queue=26658352, util=100.00%, aggrios=58194070/26591, aggrmerge=0/0, aggrticks=8834468/168569, aggrin_queue=9026514, aggrutil=100.00% dm-1: ios=15/46976, merge=0/0, ticks=0/8080, in_queue=8084, util=0.35%, aggrios=174561550/46008, aggrmerge=1/6963, aggrticks=26076884/8636, aggrin_queue=26119484, aggrutil=100.00% xvdc: ios=174561550/46008, merge=1/6963, ticks=26076884/8636, in_queue=26119484, util=100.00% dm-0: ios=174561536/6745, merge=0/0, ticks=26039312/1316, in_queue=26111052, util=100.00% dm-3: ios=20660/26054, merge=0/0, ticks=464092/496312, in_queue=960408, util=5.44%, aggrios=20660/26051, aggrmerge=0/3, aggrticks=464080/495444, aggrin_queue=959516, aggrutil=5.44% xvdd: ios=20660/26051, merge=0/3, ticks=464080/495444, in_queue=959516, util=5.44% 4GiB data $ (cd /srv/cache/fio && FIOTEST=cachesize-4g-full fio ~/cachesize-4g.fio) cachesize-4g: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8 ... fio-2.16 Starting 2 processes cachesize-4g: Laying out IO file(s) (1 file(s) / 2048MB) cachesize-4g: Laying out IO file(s) (1 file(s) / 2048MB) Jobs: 2 (f=2): [r(2)] [100.0% done] [375.8MB/0KB/0KB /s] [96.2K/0/0 iops] [eta 00m:00s] cachesize-4g: (groupid=0, jobs=1): err= 0: pid=26795: Wed Aug 2 16:22:51 2017 read : io=249614MB, bw=142002KB/s, iops=35500, runt=1800001msec slat (usec): min=0, max=4469, avg= 7.00, stdev= 4.50 clat (usec): min=9, max=1363.9K, avg=215.84, stdev=3099.68 lat (usec): min=65, max=1363.9K, avg=223.29, stdev=3099.98 clat percentiles (usec): | 1.00th=[ 103], 5.00th=[ 109], 10.00th=[ 114], 20.00th=[ 121], | 30.00th=[ 127], 40.00th=[ 133], 50.00th=[ 139], 60.00th=[ 147], | 70.00th=[ 159], 80.00th=[ 177], 90.00th=[ 211], 95.00th=[ 255], | 99.00th=[ 354], 99.50th=[ 402], 99.90th=[ 4384], 99.95th=[35072], | 99.99th=[142336] lat (usec) : 10=0.01%, 50=0.01%, 100=0.30%, 250=94.32%, 500=5.21% lat (usec) : 750=0.06%, 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.02%, 50=0.03% lat (msec) : 100=0.02%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01% lat (msec) : 2000=0.01% cpu : usr=10.92%, sys=38.72%, ctx=29995970, majf=0, minf=16 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=63901149/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 cachesize-4g: (groupid=0, jobs=1): err= 0: pid=26796: Wed Aug 2 16:22:51 2017 read : io=239913MB, bw=136484KB/s, iops=34120, runt=1800001msec slat (usec): min=0, max=4613, avg= 7.08, stdev= 4.64 clat (usec): min=20, max=1315.4K, avg=224.86, stdev=3340.78 lat (usec): min=67, max=1315.4K, avg=232.39, stdev=3341.07 clat percentiles (usec): | 1.00th=[ 103], 5.00th=[ 110], 10.00th=[ 116], 20.00th=[ 122], | 30.00th=[ 127], 40.00th=[ 133], 50.00th=[ 139], 60.00th=[ 147], | 70.00th=[ 157], 80.00th=[ 177], 90.00th=[ 219], 95.00th=[ 274], | 99.00th=[ 390], 99.50th=[ 442], 99.90th=[10304], 99.95th=[39680], | 99.99th=[154624] lat (usec) : 50=0.01%, 100=0.27%, 250=92.97%, 500=6.52%, 750=0.12% lat (usec) : 1000=0.01% lat (msec) : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.02%, 50=0.04% lat (msec) : 100=0.02%, 250=0.02%, 500=0.01%, 750=0.01%, 1000=0.01% lat (msec) : 2000=0.01% cpu : usr=10.28%, sys=37.64%, ctx=29036049, majf=0, minf=14 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=61417783/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 Run status group 0 (all jobs): READ: io=489527MB, aggrb=278486KB/s, minb=136483KB/s, maxb=142002KB/s, mint=1800001msec, maxt=1800001msec Disk stats (read/write): dm-2: ios=125296525/29, merge=0/0, ticks=27228000/6004, in_queue=27295900, util=100.00%, aggrios=41794883/193226, aggrmerge=0/0, aggrticks=9825693/38738, aggrin_queue=9881421, aggrutil=84.96% dm-1: ios=86/514016, merge=0/0, ticks=16/61332, in_queue=61376, util=2.08%, aggrios=125186978/561183, aggrmerge=0/17273, aggrticks=18938212/71188, aggrin_queue=19034916, aggrutil=85.91% xvdc: ios=125186978/561183, merge=0/17273, ticks=18938212/71188, in_queue=19034916, util=85.91% dm-0: ios=125186892/64571, merge=0/0, ticks=18904024/11972, in_queue=18966848, util=84.96% dm-3: ios=197671/1091, merge=0/0, ticks=10573040/42912, in_queue=10616040, util=33.53%, aggrios=197671/1084, aggrmerge=0/7, aggrticks=10573020/39132, aggrin_queue=10612148, aggrutil=33.53% xvdd: ios=197671/1084, merge=0/7, ticks=10573020/39132, in_queue=10612148, util=33.53% 8GiB data $ (cd /srv/cache/fio && FIOTEST=cachesize-8g-full fio ~/cachesize-8g.fio) cachesize-8g: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8 ... fio-2.16 Starting 2 processes cachesize-8g: Laying out IO file(s) (1 file(s) / 4096MB) cachesize-8g: Laying out IO file(s) (1 file(s) / 4096MB) Jobs: 2 (f=2): [r(2)] [100.0% done] [18048KB/0KB/0KB /s] [4512/0/0 iops] [eta 00m:00s] cachesize-8g: (groupid=0, jobs=1): err= 0: pid=15599: Wed Aug 2 14:53:25 2017 read : io=13260MB, bw=7542.7KB/s, iops=1885, runt=1800146msec slat (usec): min=0, max=385, avg= 8.25, stdev= 5.69 clat (usec): min=9, max=1516.6K, avg=4231.66, stdev=26655.31 lat (usec): min=69, max=1516.6K, avg=4240.38, stdev=26657.41 clat percentiles (usec): | 1.00th=[ 101], 5.00th=[ 104], 10.00th=[ 105], 20.00th=[ 107], | 30.00th=[ 109], 40.00th=[ 116], 50.00th=[ 119], 60.00th=[ 121], | 70.00th=[ 122], 80.00th=[ 124], 90.00th=[ 159], 95.00th=[16064], | 99.00th=[113152], 99.50th=[175104], 99.90th=[358400], 99.95th=[456704], | 99.99th=[700416] lat (usec) : 10=0.01%, 100=0.45%, 250=92.98%, 500=0.41%, 750=0.05% lat (usec) : 1000=0.04% lat (msec) : 2=0.08%, 4=0.01%, 10=0.22%, 20=1.29%, 50=2.04% lat (msec) : 100=1.25%, 250=0.93%, 500=0.21%, 750=0.03%, 1000=0.01% lat (msec) : 2000=0.01% cpu : usr=0.95%, sys=2.94%, ctx=3521460, majf=0, minf=17 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=3394445/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 cachesize-8g: (groupid=0, jobs=1): err= 0: pid=15600: Wed Aug 2 14:53:25 2017 read : io=13886MB, bw=7899.2KB/s, iops=1974, runt=1800112msec slat (usec): min=0, max=2743, avg= 8.26, stdev= 5.84 clat (usec): min=2, max=1515.1K, avg=4040.21, stdev=24950.67 lat (usec): min=69, max=1515.1K, avg=4048.94, stdev=24952.83 clat percentiles (usec): | 1.00th=[ 100], 5.00th=[ 103], 10.00th=[ 105], 20.00th=[ 107], | 30.00th=[ 108], 40.00th=[ 110], 50.00th=[ 118], 60.00th=[ 120], | 70.00th=[ 121], 80.00th=[ 123], 90.00th=[ 157], 95.00th=[15552], | 99.00th=[109056], 99.50th=[166912], 99.90th=[333824], 99.95th=[419840], | 99.99th=[634880] lat (usec) : 4=0.01%, 100=0.56%, 250=92.98%, 500=0.31%, 750=0.05% lat (usec) : 1000=0.05% lat (msec) : 2=0.07%, 4=0.01%, 10=0.24%, 20=1.33%, 50=2.04% lat (msec) : 100=1.25%, 250=0.91%, 500=0.19%, 750=0.02%, 1000=0.01% lat (msec) : 2000=0.01% cpu : usr=0.94%, sys=3.09%, ctx=3684550, majf=0, minf=15 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=3554777/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 Run status group 0 (all jobs): READ: io=27145MB, aggrb=15441KB/s, minb=7542KB/s, maxb=7899KB/s, mint=1800112msec, maxt=1800146msec Disk stats (read/write): dm-2: ios=6948764/45, merge=0/0, ticks=28718292/11380, in_queue=28731160, util=100.00%, aggrios=2383761/603042, aggrmerge=0/0, aggrticks=12202621/76005, aggrin_queue=12278754, aggrutil=100.00% dm-1: ios=48/1607066, merge=0/0, ticks=4/178612, in_queue=178652, util=5.79%, aggrios=6527499/1756743, aggrmerge=0/51937, aggrticks=781204/210664, aggrin_queue=991672, aggrutil=41.93% xvdc: ios=6527499/1756743, merge=0/51937, ticks=781204/210664, in_queue=991672, util=41.93% dm-0: ios=6527451/202019, merge=0/0, ticks=780348/38028, in_queue=818476, util=38.13% dm-3: ios=623784/41, merge=0/0, ticks=35827512/11376, in_queue=35839136, util=100.00%, aggrios=623784/10, aggrmerge=0/31, aggrticks=35827612/2744, aggrin_queue=35830320, aggrutil=100.00% xvdd: ios=623784/10, merge=0/31, ticks=35827612/2744, in_queue=35830320, util=100.00% 16GiB data $ (cd /srv/cache/fio && FIOTEST=cachesize-16g-full fio ~/cachesize-16g.fio) cachesize-16g: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8 ... fio-2.16 Starting 2 processes cachesize-16g: Laying out IO file(s) (1 file(s) / 8192MB) cachesize-16g: Laying out IO file(s) (1 file(s) / 8192MB) Jobs: 2 (f=2): [r(2)] [100.0% done] [8288KB/0KB/0KB /s] [2072/0/0 iops] [eta 00m:00s] cachesize-16g: (groupid=0, jobs=1): err= 0: pid=2957: Wed Aug 2 13:13:01 2017 read : io=5417.5MB, bw=3081.9KB/s, iops=770, runt=1800060msec slat (usec): min=0, max=264, avg=10.14, stdev= 6.63 clat (usec): min=64, max=1972.9K, avg=10370.01, stdev=35718.97 lat (usec): min=71, max=1972.9K, avg=10380.72, stdev=35719.88 clat percentiles (usec): | 1.00th=[ 102], 5.00th=[ 105], 10.00th=[ 107], 20.00th=[ 116], | 30.00th=[ 119], 40.00th=[ 121], 50.00th=[ 122], 60.00th=[ 131], | 70.00th=[ 143], 80.00th=[ 165], 90.00th=[31104], 95.00th=[65280], | 99.00th=[173056], 99.50th=[228352], 99.90th=[374784], 99.95th=[440320], | 99.99th=[618496] lat (usec) : 100=0.28%, 250=82.96%, 500=0.10%, 750=0.04%, 1000=0.03% lat (msec) : 2=0.06%, 4=0.02%, 10=0.38%, 20=3.05%, 50=6.44% lat (msec) : 100=3.82%, 250=2.43%, 500=0.36%, 750=0.02%, 1000=0.01% lat (msec) : 2000=0.01% cpu : usr=0.40%, sys=1.39%, ctx=1393813, majf=0, minf=16 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=1386875/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 cachesize-16g: (groupid=0, jobs=1): err= 0: pid=2958: Wed Aug 2 13:13:01 2017 read : io=6208.7MB, bw=3531.9KB/s, iops=882, runt=1800089msec slat (usec): min=0, max=437, avg=10.21, stdev= 6.74 clat (usec): min=1, max=1988.1K, avg=9046.94, stdev=31703.98 lat (usec): min=71, max=1989.2K, avg=9057.72, stdev=31704.93 clat percentiles (usec): | 1.00th=[ 101], 5.00th=[ 104], 10.00th=[ 105], 20.00th=[ 107], | 30.00th=[ 112], 40.00th=[ 119], 50.00th=[ 121], 60.00th=[ 125], | 70.00th=[ 137], 80.00th=[ 157], 90.00th=[27776], 95.00th=[57088], | 99.00th=[152576], 99.50th=[201728], 99.90th=[329728], 99.95th=[395264], | 99.99th=[577536] lat (usec) : 2=0.01%, 50=0.01%, 100=0.41%, 250=83.62%, 500=0.09% lat (usec) : 750=0.04%, 1000=0.03% lat (msec) : 2=0.05%, 4=0.01%, 10=0.39%, 20=3.06%, 50=6.51% lat (msec) : 100=3.52%, 250=2.00%, 500=0.25%, 750=0.01%, 1000=0.01% lat (msec) : 2000=0.01% cpu : usr=0.53%, sys=1.56%, ctx=1597691, majf=0, minf=15 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=1589415/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 Run status group 0 (all jobs): READ: io=11626MB, aggrb=6613KB/s, minb=3081KB/s, maxb=3531KB/s, mint=1800060msec, maxt=1800089msec Disk stats (read/write): dm-2: ios=2976172/77, merge=0/0, ticks=28759760/45044, in_queue=28805924, util=100.00%, aggrios=998518/56115, aggrmerge=0/0, aggrticks=9860773/22645, aggrin_queue=9883437, aggrutil=100.00% dm-1: ios=88/149089, merge=0/0, ticks=4/18444, in_queue=18452, util=0.58%, aggrios=2489913/161345, aggrmerge=0/6821, aggrticks=314936/21908, aggrin_queue=336800, aggrutil=17.38% xvdc: ios=2489913/161345, merge=0/6821, ticks=314936/21908, in_queue=336800, util=17.38% dm-0: ios=2489825/19183, merge=0/0, ticks=314816/4448, in_queue=319308, util=16.88% dm-3: ios=505643/74, merge=0/0, ticks=29267500/45044, in_queue=29312552, util=100.00%, aggrios=505643/12, aggrmerge=0/62, aggrticks=29267500/10580, aggrin_queue=29278060, aggrutil=100.00% xvdd: ios=505643/12, merge=0/62, ticks=29267500/10580, in_queue=29278060, util=100.00% 32GiB data $ (cd /srv/cache/fio && FIOTEST=cachesize-32g-full fio ~/cachesize-32g.fio) cachesize-32g: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8 ... fio-2.16 Starting 2 processes cachesize-32g: Laying out IO file(s) (1 file(s) / 16384MB) cachesize-32g: Laying out IO file(s) (1 file(s) / 16384MB) Jobs: 2 (f=2): [r(2)] [100.0% done] [4624KB/0KB/0KB /s] [1156/0/0 iops] [eta 00m:00s] cachesize-32g: (groupid=0, jobs=1): err= 0: pid=23915: Wed Aug 2 11:42:12 2017 read : io=3378.9MB, bw=1922.5KB/s, iops=480, runt=1800108msec slat (usec): min=0, max=152, avg=11.84, stdev= 9.33 clat (usec): min=61, max=1523.8K, avg=16633.48, stdev=52554.00 lat (usec): min=68, max=1523.8K, avg=16645.89, stdev=52556.11 clat percentiles (usec): | 1.00th=[ 100], 5.00th=[ 104], 10.00th=[ 106], 20.00th=[ 108], | 30.00th=[ 117], 40.00th=[ 121], 50.00th=[ 123], 60.00th=[ 133], | 70.00th=[ 147], 80.00th=[ 8768], 90.00th=[49920], 95.00th=[104960], | 99.00th=[257024], 99.50th=[333824], 99.90th=[536576], 99.95th=[626688], | 99.99th=[880640] lat (usec) : 100=0.57%, 250=78.79%, 500=0.19%, 750=0.06%, 1000=0.05% lat (msec) : 2=0.09%, 4=0.02%, 10=0.47%, 20=2.96%, 50=6.82% lat (msec) : 100=4.70%, 250=4.22%, 500=0.94%, 750=0.11%, 1000=0.02% lat (msec) : 2000=0.01% cpu : usr=0.34%, sys=0.87%, ctx=916902, majf=0, minf=18 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=864974/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 cachesize-32g: (groupid=0, jobs=1): err= 0: pid=23916: Wed Aug 2 11:42:12 2017 read : io=5022.5MB, bw=2857.5KB/s, iops=714, runt=1800090msec slat (usec): min=0, max=173, avg=11.35, stdev= 9.15 clat (usec): min=62, max=1768.2K, avg=11185.81, stdev=48075.30 lat (usec): min=70, max=1768.2K, avg=11197.69, stdev=48077.75 clat percentiles (usec): | 1.00th=[ 101], 5.00th=[ 104], 10.00th=[ 106], 20.00th=[ 108], | 30.00th=[ 115], 40.00th=[ 120], 50.00th=[ 122], 60.00th=[ 125], | 70.00th=[ 137], 80.00th=[ 153], 90.00th=[26240], 95.00th=[63744], | 99.00th=[220160], 99.50th=[309248], 99.90th=[585728], 99.95th=[733184], | 99.99th=[1122304] lat (usec) : 100=0.46%, 250=85.40%, 500=0.22%, 750=0.06%, 1000=0.04% lat (msec) : 2=0.07%, 4=0.02%, 10=0.25%, 20=2.04%, 50=5.27% lat (msec) : 100=2.99%, 250=2.39%, 500=0.62%, 750=0.12%, 1000=0.03% lat (msec) : 2000=0.02% cpu : usr=0.50%, sys=1.27%, ctx=1372044, majf=0, minf=17 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=1285733/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 Run status group 0 (all jobs): READ: io=8401.3MB, aggrb=4779KB/s, minb=1922KB/s, maxb=2857KB/s, mint=1800090msec, maxt=1800108msec Disk stats (read/write): dm-2: ios=2150707/143, merge=0/0, ticks=28767744/34836, in_queue=28804592, util=100.00%, aggrios=751272/286183, aggrmerge=0/0, aggrticks=11166794/101613, aggrin_queue=11268450, aggrutil=100.00% dm-1: ios=62/755357, merge=0/0, ticks=12/85084, in_queue=85108, util=2.67%, aggrios=1798588/823298, aggrmerge=494/28038, aggrticks=232996/102144, aggrin_queue=335068, aggrutil=15.62% xvdc: ios=1798588/823298, merge=494/28038, ticks=232996/102144, in_queue=335068, util=15.62% dm-0: ios=1799020/96389, merge=0/0, ticks=234124/20548, in_queue=254704, util=13.23% dm-3: ios=454734/6803, merge=0/0, ticks=33266248/199208, in_queue=33465540, util=100.00%, aggrios=454734/6184, aggrmerge=0/619, aggrticks=33266152/97928, aggrin_queue=33364124, aggrutil=100.00% xvdd: ios=454734/6184, merge=0/619, ticks=33266152/97928, in_queue=33364124, util=100.00% 48GiB data $ (cd /srv/cache/fio && FIOTEST=cachesize-48g-full fio ~/cachesize-48g.fio) cachesize-48g: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8 ... fio-2.16 Starting 2 processes cachesize-48g: Laying out IO file(s) (1 file(s) / 24576MB) cachesize-48g: Laying out IO file(s) (1 file(s) / 24576MB) Jobs: 2 (f=2): [r(2)] [100.0% done] [4084KB/0KB/0KB /s] [1021/0/0 iops] [eta 00m:00s] cachesize-48g: (groupid=0, jobs=1): err= 0: pid=11765: Tue Aug 1 12:02:44 2017 read : io=3108.7MB, bw=1768.4KB/s, iops=442, runt=1800134msec slat (usec): min=0, max=75057, avg=12.49, stdev=100.40 clat (usec): min=61, max=7717.4K, avg=18080.36, stdev=79780.10 lat (usec): min=70, max=7717.4K, avg=18093.41, stdev=79783.33 clat percentiles (usec): | 1.00th=[ 101], 5.00th=[ 104], 10.00th=[ 106], 20.00th=[ 108], | 30.00th=[ 115], 40.00th=[ 120], 50.00th=[ 124], 60.00th=[ 133], | 70.00th=[ 145], 80.00th=[ 197], 90.00th=[44288], 95.00th=[103936], | 99.00th=[296960], 99.50th=[419840], 99.90th=[1028096], 99.95th=[1269760], | 99.99th=[2179072] lat (usec) : 100=0.49%, 250=81.20%, 500=0.22%, 750=0.05%, 1000=0.04% lat (msec) : 2=0.07%, 4=0.03%, 10=0.34%, 20=2.26%, 50=6.08% lat (msec) : 100=4.04%, 250=3.79%, 500=1.03%, 750=0.19%, 1000=0.07% lat (msec) : 2000=0.09%, >=2000=0.01% cpu : usr=0.37%, sys=0.78%, ctx=846462, majf=0, minf=17 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=795801/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 cachesize-48g: (groupid=0, jobs=1): err= 0: pid=11766: Tue Aug 1 12:02:44 2017 read : io=3181.9MB, bw=1809.1KB/s, iops=452, runt=1800123msec slat (usec): min=0, max=177, avg=12.61, stdev=10.17 clat (usec): min=51, max=4963.9K, avg=17663.67, stdev=73795.84 lat (usec): min=68, max=4963.1K, avg=17676.84, stdev=73797.60 clat percentiles (usec): | 1.00th=[ 101], 5.00th=[ 105], 10.00th=[ 107], 20.00th=[ 110], | 30.00th=[ 118], 40.00th=[ 122], 50.00th=[ 129], 60.00th=[ 137], | 70.00th=[ 151], 80.00th=[ 9664], 90.00th=[48384], 95.00th=[99840], | 99.00th=[259072], 99.50th=[354304], 99.90th=[978944], 99.95th=[1269760], | 99.99th=[2179072] lat (usec) : 100=0.47%, 250=78.72%, 500=0.21%, 750=0.06%, 1000=0.05% lat (msec) : 2=0.09%, 4=0.03%, 10=0.43%, 20=2.92%, 50=7.31% lat (msec) : 100=4.70%, 250=3.92%, 500=0.82%, 750=0.12%, 1000=0.05% lat (msec) : 2000=0.08%, >=2000=0.02% cpu : usr=0.40%, sys=0.80%, ctx=867597, majf=0, minf=16 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=100.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=814542/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 Run status group 0 (all jobs): READ: io=6290.5MB, aggrb=3578KB/s, minb=1768KB/s, maxb=1809KB/s, mint=1800123msec, maxt=1800134msec Disk stats (read/write): dm-2: ios=1610343/207, merge=0/0, ticks=28775436/83448, in_queue=28860328, util=100.00%, aggrios=562278/204739, aggrmerge=0/0, aggrticks=11044750/380021, aggrin_queue=11424792, aggrutil=100.00% dm-1: ios=53/537570, merge=0/0, ticks=4/63980, in_queue=64000, util=1.97%, aggrios=1303106/589473, aggrmerge=993/17280, aggrticks=184484/78092, aggrin_queue=262524, aggrutil=11.76% xvdc: ios=1303106/589473, merge=993/17280, ticks=184484/78092, in_queue=262524, util=11.76% dm-0: ios=1304046/69309, merge=0/0, ticks=188420/16684, in_queue=205128, util=9.97% dm-3: ios=382737/7340, merge=0/0, ticks=32945828/1059400, in_queue=34005248, util=100.00%, aggrios=382737/6163, aggrmerge=0/1177, aggrticks=32945132/641880, aggrin_queue=33587056, aggrutil=100.00% xvdd: ios=382737/6163, merge=0/1177, ticks=32945132/641880, in_queue=33587056, util=100.00%
Categories: LUG Community Blogs

Steve Kemp: So I did a thing, then another thing.

Planet HantsLUG - Wed, 02/08/2017 - 21:00

So I did start a project, to write a puppet-dashboard, it is functionally complete, but the next step is to allow me to raise alerts based on failing runs of puppet - in real-time.

(i.e. Now that I have a dashboard I wish to not use it. I want to be alerted to failures, without having to remember to go look for them. Something puppet-dashboard can't do ..)

In other news a while back I slipped in a casual note about having a brain scan done, here in sunny Helsinki.

One of the cool things about that experience, in addition to being told I wasn't going to drop dead that particular day, was that the radiologist told me that I could pay €25 to get a copy of my brain data in DICOM format.

I've not yet played with this very much, but I couldn't resist a brief animation:

  • See my brain.
    • Not the best quality, or the best detail, but damn. It is my brain.
    • I shall do better with more experimentation I think.
    • After I posted it my wife, a doctor, corrected me: That wasn't a gif of my brain, instead it was a gif of my skull. D'oh!
Categories: LUG Community Blogs

Mick Morgan: a letter to our dear home secretary

Planet ALUG - Wed, 02/08/2017 - 14:56

Dear Amber

So,”real people” don’t care about privacy? All they really want is ease of use and a pretty GUI so that they can chat to all their friends on-line? Only “the enemy” (who is that exactly anyway?) needs encryption? Excuse me for asking, but what have you been smoking? Does the Home Office know about that?

I’m a real person. And I care deeply about privacy. I care enough to fund both my own Tor node and various openVPN servers dotted around the world just to get past your ludicrous attempts at gratuitous surveillance of my (and my family’s) routine use of the ‘net. I care about the security and privacy of my transactions with various commercial enterprises, including my bank (which is why I expect them to use TLS on their website). I care about privacy when I correspond with my Doctor and other professionals. I care about privacy when I use an on-line search engine (which, incidentally, is not Google). I care about privacy because privacy matters. I have the right to freedom of thought and expression. I have the right to discuss those thoughts with others of my choice – when I choose and how I choose. You may not like that, but it’s a fact of life. That doesn’t make me “the enemy”. Get over it.

Love and Kisses

Mick

(Note to readers: Aral Balkan has deconstructed Rudd’s ramblings. I commend the article to you.)

Categories: LUG Community Blogs

Bring-A-Box, Saturday 11 June 2016, All Saints, Mitcham

Surrey LUG - Fri, 15/04/2016 - 18:54
Start: 2016-06-11 12:00 End: 2016-06-11 12:00

We have regular sessions on the second Saturday of each month. Bring a 'box', bring a notebook, bring anything that might run Linux, or just bring yourself and enjoy socialising/learning/teaching or simply chilling out!

This month's meeting is at the All Saints Centre, Mitcham, Surrey.  CR4 4JN

New members are very welcome. We're not a cliquey bunch, so you won't feel out of place! Usually between 15 and 30 people come along.

Categories: LUG Community Blogs

Bring-A-Box, Saturday 14th May 2016

Surrey LUG - Fri, 15/04/2016 - 18:50
Start: 2016-05-14 12:00 End: 2016-05-14 12:00

Venue to be found.  Watch this space!  No!  Better still, find a venue and discuss it on the mailing list!

Categories: LUG Community Blogs

Bring-A-Box, Saturday 9th April 2016, Station pub, W Byfleet

Surrey LUG - Thu, 07/04/2016 - 15:04
Start: 2016-04-09 12:00 End: 2016-04-09 12:00

We have regular sessions on the second Saturday of each month. Bring a 'box', bring a notebook, bring anything that might run Linux, or just bring yourself and enjoy socialising/learning/teaching or simply chilling out!

This month's meeting is at the Station Pub in West Byfleet, Surrey.

New members are very welcome. We're not a cliquey bunch, so you won't feel out of place! Usually between 15 and 30 people come along.

Categories: LUG Community Blogs
Syndicate content