How I do "NVMe overprovisioning"? - namespaces

I want to use NVMe overprovisioning on a NVMe disk with ZFS. I have read this: https://openzfs.github.io/openzfs-docs/Performance%20and%20Tuning/Workload%20Tuning.html?highlight=ashift#nvme-overprovisioning
But I don't understand the "Create a new namespace of size 4GB." step. How is it done? Do it mean to create a 4GB partition?

While it's possible to achieve overprovisioning by partitioning less than a full device, creating a namespace on an nvme is different from creating a partition. The OS will see a namespace as a device. If you create multiple namspaces on an NVMe drive, the OS will see multiple devices and can create an independent partition table on each device.
This is useful in a multitenant environment where you may want to expose only certain namespaces to a tenant. It can also be useful if your OS installer uses the whole device and doesn't give you the option of overprovisioning by creating smaller partitions. The ESXi installer does this, and I think Truenas as well. In these cases, overprovisioning with a namespace prevents the installer from claiming the whole drive.
If the above cases don't apply to you then you can overprovision with your partitions. However if you want to use namespaces to overprovision an NVMe device, then here is how you might go about it. Note that this is only possible if the NVMe device supports more than one namespaces. Many devices support only a single namespace, and if this is the case, you won't be able to use it to overprovision the device.
The examples below assume your device is /dev/nvme0 and that it supports 4k sectors.
Check how many namespaces the device supports.
nvme id-ctrl /dev/nvme0 | grep ^nn
If it returns '1', you can't delete or create namespaces on the device. If more than one, continue by deleting the first namespace.
nvme delete-ns /dev/nvme0 -n 1
Create a new namespace 4GB in size with 4k sectors.
nvme create-ns /dev/nvme0 -b 4096 -s 4194304
There are many great resources for learning more about nvme-cli and how to manage your NVMe devices. I referenced the following pages for the information I provided above.
https://narasimhan-v.github.io/2020/06/12/Managing-NVMe-Namespaces.html
https://www.drewthorst.com/posts/nvme/namespaces/readme/

Related

qemu-system-arm and lm3s6965evb / Cortex M3 ... need more ram

I'm successfully compiling my unit-test with arm-eabi-none-gcc and running them in qemu-system-arm with the machine lm3s6965evb.... But for some of the unit-tests I need more than the 64k of RAM that the lm3s6965evb mcu/machine has.
The IAR simulator apparently has no hard limit in the 'machine', so I just made a phony linkerfile that allows the unittest-program to use e.g. 512k RAM. This works (surprisingly) fine , but qemu doesn't play like that (hangs the moment I change the RAM section in the linkerfile). So I need another machine...
But thinking about it: I think I just need something that executes ARMv7 thumb(2?) code, like the CortexM3. It could also be Cortex-M33 which is a ARMv8 ...
I don't care about Hardware-registers or interrupts etc. I do need, however, printf() to work via semihosting or other means (uart etc), to printout unittest status (success/failures)
What are my best candidates,
modify the lm3s6965evb somehow?
taking an A7?
taking some of the ARM vhdl/fpga machines? (msp2.. musca ...) ?
(The 'virt' machine does not support cortex-m3/m4, according to error message)
?
Thanks
/T
(It turns out, that I misread the "mps2-an385" documentation & tutorials, - it wasn't complicated at all.)
It works if I just use the "mps2-an385" machine and modify the linkerfile to use more flash and ram. Currently i beefed it up to 4x ram and flash which is enough currently. (Haven't found out what the exact limits are.)
Still, I would like to hear if there are other solutions.
QEMU's lm3s6965evb model follows the real hardware, which does not have much RAM. If you want more RAM and you don't specifically want to have a model of those Stellaris boards, pick a board model type which has more RAM. If you need to use an M-profile core, try one of the MPS2 boards. If you are happy with an A-profile core, then the "virt" board with a Cortex-A15 may be a good choice.

Loading different elf on qemu arm cores

I'm using QEMU-4.1.0 aarch64 to emulate some multi-core systems. Is it possible to run different elfs on different cores?
I am trying to use qemu provided function arm_load_kernel (
https://github.com/qemu/qemu/blob/master/hw/arm/boot.c line:1275) during my board initialization, but am not able to load different elfs.
If you want to load more than one ELF file then you should look at the 'generic loader' documented in docs/generic-loader.txt. This also lets you specify which CPU, if any, should have its PC set to the entry point of the ELF file. Depending on the board, you might be able to load all the ELF files that way and not specify -kernel at all. The command line for it is '-device loader,[options...]'.
Note that if you are using a board model which starts with most of the CPUs in a 'power off' state (ie where the expectation is that the primary CPU will power the other CPUs on) then you'll need to have code to do that whether you have one ELF or several (or, if the board permits it, use suitable command line options to have all the CPUs start powered on).

Type-1 Hypervisors non-volatile memory isolation

Hypervisors isolate different OS running on the same physical machine from each other. Within this definition, non-volatile memory (like hard-drives or flash) separation exists as well.
When thinking on Type-2 hypervisors, it is easy to understand how they separate non-volatile memory because they just use the file system implementation of the underlying OS to allocate different "hard-drive files" to each VM.
But than, when i come to think about Type-1 hypervisors, the problem becomes harder. They can use IOMMU to isolate different hardware interfaces, but in the case of just one non-volatile memory interface in the system I don't see how it helps.
So one way to implement it will be to separate one device into 2 "partitions", and make the hypervisor interpret calls from the VMs and decide whether the calls are legit or not. I'm not keen on communication protocols to non-volatile interfaces but the hypervisor will have to be be familiar with those protocols in order to make the verdict, which sounds (maybe) like an overkill.
Are there other ways to implement this kind of isolation?
Yes you are right, hypervisor will have to be be familiar with those protocols in order to make the isolation possible.
The overhead is mostly dependent on protocol. Like NVMe based SSD basically works on PCIe and some NVMe devices support SR-IOV which greatly reduces the effort but some don't leaving the burden on the hyperviosr.
Mostly this support is configured at build time, like how much memory will be given to each guest, command privilege for each guest etc, and when a guest send a command, hypervisor verifies its bounds and forwards them accordingly.
So why there is not any support like MMU or IOMMU in this case?
There are hundreds of types of such devices with different protocols, NVMe, AHCI etc, and if the vendor came to support these to allow better virtualization, he will end up with a huge chip that's not gonna fit in.

Run my application in a simulated low memory, slow CPU environment

I want to stress-test my application this way, because it seems to be failing in some very old client machines.
At first I read a bit about QEmu and thought about hardware emulation, but it seems a long shot. I asked at superuser, but didn't get much feedback (yet).
So I'm turning to you guys... How do you this kind of testing?
I'm not sure about slowing a CPU but if you use a virtual machine, like VMWare, you can control how much RAM is actually used. I run it on a MBP at home with 8GB and my WinXP VM is capped at 1.5 GB RAM.
EDIT: I just checked my version of VMWare and I can control the number of cores it can use. It's definitely not the same as a slower CPU but it might highlight some issues for you.
Since it's not entirely clear that your app is failing because of the old hardware or the old OS, a VM client should allow you to test various versions of OSes rather quickly. It came in handy for me a few years back when I was trying to get a .Net 2.0 app to run on Win98 (it can be done though I don't remember how I got it working...).
Virtual Box is a free virtual machine similar to VMWare. It also has the capacity to reduce available memory. It can restrict how many CPUs are available, but not how fast those CPUs are.
Try cpulimit, most distro includes it (Ubuntu does) http://www.digipedia.pl/man/doc/view/cpulimit.1
If you want to lower the speed of your cpu you can easily do this by modifying a fork bomb program
int main(){
int x=0;
int limit = 10
while( x < limit ){
int pid = fork();
if( pid == 0 )
while( 1 ){}
else
x++;
}
}
This will slow down your computer quite quickly, you may want to change the limit variable to a higher number. I must warn you though this can be dangerous, because if implemented wrong you could fork bomb your system leaving it useless unless you restart it. Read this first if you don't understand what this code will do.
On POSIX (Unix) systems you can apply run limits to processes (that is, to executions of a program). The system call to do this is called setrlimit(), and most shells enable you to use the ulimit built-in to set them from the command-line (plain POSIX ulimit is not very useful). Using these you can run a program with low limits to simulate a smaller computer.
POSIX systems also provide a nice command for running a program at lower CPU priority, which can simulate a slower CPU if you also ensure there is another CPU intensive progam running at the same time.
I think it's pretty unlikely that cpu speed is going to exercise very many bugs; On the other hand, it's much more likely for different cpu features to matter. Many VM implementations provide ways of toggling on and off certain cpu features; qemu in particular permits a high level of control over what's available to the CPU.
Think outside the box. Which application of the ones you use regularly does this?
A debugger of course! But, how can you achieve such a behavior, to emulate a low cpu?
The secret to your question is asm _int 3. This is the assembly "pause me" command that is send from the attached debugger to the application you are debugging.
More about int 3 to this question.
You can use the code from this tool to pause/resume your process continuously. You can add an interval and make that tool pause your application for that amount of time.
The emulated-cpu-speed would be: (YourCPU/Interval) -0.00001% because of the signaling and other processes running on your machine, but it should do the trick.
About the low memory emulation:
You can create a wrapper class that allocates memory for the application and replace each allocation with call to this class. You would be able to set exactly the amount of memory your application can use before it fails to allocate more memory.
Something such as: MyClass* foo = AllocWrapper(new MyClass(arguments or whatever));
Then you can have the AllocWrapper allocating/deallocating memory for you.
On Linux, you can use ulimit as Raedwald said. On Windows, you can use the SetProcessWorkingSetSize system call. But these only set a limit on a per process basis. In reality, parts of the system will start to fail in a stressed environment. I would suggest using the Sysinternals' testlimit tool to stress the entire machine.
See https://serverfault.com/questions/36309/throttle-down-cpu-speed-of-vmware-image
were it is claimed free-as-in-beer VMware vSphere Hypervisorâ„¢ (ESXi) allows you to select the virtual CPU speed on top of setting the memory size of the virtual machine.

What language(s) for very large lists?

Java (and maybe the underlying C-ish code) has max capacity of Integer.MAX_VALUE (~ 2 billion) for arrays and containers in java.util. Are there other languages that feature containers with larger capacities?
You don't want languages, you want databases.
You can write your own containers in both languages that support long indices.
If you're starting to hit the 32-bit limit of a number in relation to the number of elements you can store in a list/array/collection, then I would seriously start finding a new way to implement your algorithm.
You're going to have lots of "we need this specialized hardware in order to execute our program" type of requirements.
STL containers in C++ use size_t indices, which are 64-bit on a 64-bit machine.
Do you have a machine with enough RAM to use more? O_o If you do, I'd say you need your own collection, because performance of the builtin ones will doubtfully scale...
There is no limit if you write your own container.
I normally use a database to store that large amounts of data. Solves a lot of problems with scaling.
No body wants to cope with such large quantities of data in memory at once. I don't know what you're trying to do, but if you need to maximize the amount of resident data you must take in account:
First use dynamic memory allocation.
You may try (in your OS) to maximize the user-mode virtual memory addressing space, if this is an option. e.g. 32-bit Windows can use the typical 2GB/2GB addressing spaces for usermode/kernel or 3GB/1GB.
Always monitor your commit memory/OS commit limit so you don't force the OS to thrash, slowing down the entire system.
You can lock down a minimal amount of memory for exclusive use of your application. This varies from OS to OS, but e.g you can give the user to fix 256MB, 512MB, 1GB memory space for your application.
If you need to surpass the available usermode address space, there are 64-bit systems at your disposal, or 32-bit with extensions such as PAE.
Well, there are a lot of things to research, but just my 2c.
An object database may suit your purposes better.
For example, db4o.
Or, for arrays of fixed size objects, it might be worth experimenting with a memory mapped file, but you will need a language interface to the OS API for that.
edit: or just use on ORM to map your collection to a standard SQL database. These exist for most languages. For example ruby has activerecord and Java has hibernate.