Set Intel RDT "resource control" filesystem as configured.
(container *configs.Config)
| 632 | |
| 633 | // Set Intel RDT "resource control" filesystem as configured. |
| 634 | func (m *Manager) Set(container *configs.Config) error { |
| 635 | // About L3 cache schema: |
| 636 | // It has allocation bitmasks/values for L3 cache on each socket, |
| 637 | // which contains L3 cache id and capacity bitmask (CBM). |
| 638 | // Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..." |
| 639 | // For example, on a two-socket machine, the schema line could be: |
| 640 | // L3:0=ff;1=c0 |
| 641 | // which means L3 cache id 0's CBM is 0xff, and L3 cache id 1's CBM |
| 642 | // is 0xc0. |
| 643 | // |
| 644 | // The valid L3 cache CBM is a *contiguous bits set* and number of |
| 645 | // bits that can be set is less than the max bit. The max bits in the |
| 646 | // CBM is varied among supported Intel CPU models. Kernel will check |
| 647 | // if it is valid when writing. e.g., default value 0xfffff in root |
| 648 | // indicates the max bits of CBM is 20 bits, which mapping to entire |
| 649 | // L3 cache capacity. Some valid CBM values to set in a group: |
| 650 | // 0xf, 0xf0, 0x3ff, 0x1f00 and etc. |
| 651 | // |
| 652 | // |
| 653 | // About memory bandwidth schema: |
| 654 | // It has allocation values for memory bandwidth on each socket, which |
| 655 | // contains L3 cache id and memory bandwidth. |
| 656 | // Format: "MB:<cache_id0>=bandwidth0;<cache_id1>=bandwidth1;..." |
| 657 | // For example, on a two-socket machine, the schema line could be: |
| 658 | // "MB:0=20;1=70" |
| 659 | // |
| 660 | // The minimum bandwidth percentage value for each CPU model is |
| 661 | // predefined and can be looked up through "info/MB/min_bandwidth". |
| 662 | // The bandwidth granularity that is allocated is also dependent on |
| 663 | // the CPU model and can be looked up at "info/MB/bandwidth_gran". |
| 664 | // The available bandwidth control steps are: min_bw + N * bw_gran. |
| 665 | // Intermediate values are rounded to the next control step available |
| 666 | // on the hardware. |
| 667 | // |
| 668 | // If MBA Software Controller is enabled through mount option |
| 669 | // "-o mba_MBps": mount -t resctrl resctrl -o mba_MBps /sys/fs/resctrl |
| 670 | // We could specify memory bandwidth in "MBps" (Mega Bytes per second) |
| 671 | // unit instead of "percentages". The kernel underneath would use a |
| 672 | // software feedback mechanism or a "Software Controller" which reads |
| 673 | // the actual bandwidth using MBM counters and adjust the memory |
| 674 | // bandwidth percentages to ensure: |
| 675 | // "actual memory bandwidth < user specified memory bandwidth". |
| 676 | // |
| 677 | // For example, on a two-socket machine, the schema line could be |
| 678 | // "MB:0=5000;1=7000" which means 5000 MBps memory bandwidth limit on |
| 679 | // socket 0 and 7000 MBps memory bandwidth limit on socket 1. |
| 680 | if r := container.IntelRdt; r != nil { |
| 681 | // TODO: verify that l3CacheSchema and/or memBwSchema match the |
| 682 | // existing schemata if ClosID has been specified. This is a more |
| 683 | // involved than reading the file and doing plain string comparison as |
| 684 | // the value written in does not necessarily match what gets read out |
| 685 | // (leading zeros, cache id ordering etc). |
| 686 | var schemata strings.Builder |
| 687 | for _, s := range append([]string{r.L3CacheSchema, r.MemBwSchema}, r.Schemata...) { |
| 688 | if s != "" { |
| 689 | schemata.WriteString(s) |
| 690 | schemata.WriteString("\n") |
| 691 | } |