1 /* SPDX-License-Identifier: LGPL-2.1-or-later
2 * Copyright © 2019 VMware, Inc. */
4 #include "alloc-util.h"
5 #include "extract-word.h"
7 #include "parse-util.h"
11 int tc_init(double *ret_ticks_in_usec
, uint32_t *ret_hz
) {
12 static double ticks_in_usec
= -1;
15 if (ticks_in_usec
< 0) {
16 uint32_t clock_resolution
, ticks_to_usec
, usec_to_ticks
;
17 _cleanup_free_
char *line
= NULL
;
21 r
= read_one_line_file("/proc/net/psched", &line
);
25 r
= sscanf(line
, "%08x%08x%08x%08x", &ticks_to_usec
, &usec_to_ticks
, &clock_resolution
, &hz
);
29 clock_factor
= (double) clock_resolution
/ USEC_PER_SEC
;
30 ticks_in_usec
= (double) ticks_to_usec
/ usec_to_ticks
* clock_factor
;
33 if (ret_ticks_in_usec
)
34 *ret_ticks_in_usec
= ticks_in_usec
;
41 int tc_time_to_tick(usec_t t
, uint32_t *ret
) {
48 r
= tc_init(&ticks_in_usec
, NULL
);
52 a
= t
* ticks_in_usec
;
60 int parse_tc_percent(const char *s
, uint32_t *percent
) {
66 r
= parse_permille(s
);
70 *percent
= (double) r
/ 1000 * UINT32_MAX
;
74 int tc_transmit_time(uint64_t rate
, uint32_t size
, uint32_t *ret
) {
75 return tc_time_to_tick(USEC_PER_SEC
* ((double)size
/ (double)rate
), ret
);
78 int tc_fill_ratespec_and_table(struct tc_ratespec
*rate
, uint32_t *rtab
, uint32_t mtu
) {
79 uint32_t cell_log
= 0;
85 while ((mtu
>> cell_log
) > 255)
88 for (size_t i
= 0; i
< 256; i
++) {
91 sz
= (i
+ 1) << cell_log
;
94 r
= tc_transmit_time(rate
->rate
, sz
, &rtab
[i
]);
99 rate
->cell_align
= -1;
100 rate
->cell_log
= cell_log
;
101 rate
->linklayer
= TC_LINKLAYER_ETHERNET
;
105 int parse_handle(const char *t
, uint32_t *ret
) {
106 _cleanup_free_
char *word
= NULL
;
107 uint16_t major
, minor
;
113 /* Extract the major number. */
114 r
= extract_first_word(&t
, &word
, ":", EXTRACT_DONT_COALESCE_SEPARATORS
);
122 r
= safe_atou16_full(word
, 16, &major
);
126 r
= safe_atou16_full(t
, 16, &minor
);
130 *ret
= ((uint32_t) major
<< 16) | minor
;