Skip to content

Commit fe813f1

Browse files
sangjinhanBarath Raghavan
authored andcommitted
Correct the unit of max_burst parameter for ratelimit TCs (#470)
* Correct the unit of max_burst: work/time -> work * Show max_burst on "show tc" * Add a burstiness example for rate_limit TC * Update unittest
1 parent 50391ba commit fe813f1

File tree

5 files changed

+89
-32
lines changed

5 files changed

+89
-32
lines changed

bessctl/commands.py

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -908,36 +908,55 @@ def show_worker_list(cli, worker_ids):
908908

909909

910910
def _limit_to_str(limit):
911-
buf = []
912-
913911
if 'count' in limit:
914-
buf.append('%d times' % limit['count'])
915-
916-
if 'cycle' in limit:
917-
buf.append('%.3f Mhz' % (limit['cycle'] / 1e6))
918-
919-
if 'packet' in limit:
912+
return '%d times/s' % limit['count']
913+
elif 'cycle' in limit:
914+
return '%.3f MHz' % (limit['cycle'] / 1e6)
915+
elif 'packet' in limit:
920916
if limit['packet'] < 1e3:
921-
buf.append('%.d pps' % limit['packet'])
917+
return '%.d pps' % limit['packet']
922918
elif limit['packet'] < 1e6:
923-
buf.append('%.3f kpps' % (limit['packet'] / 1e3))
919+
return '%.3f kpps' % (limit['packet'] / 1e3)
924920
else:
925-
buf.append('%.3f Mpps' % (limit['packet'] / 1e6))
926-
927-
if 'bit' in limit:
921+
return '%.3f Mpps' % (limit['packet'] / 1e6)
922+
elif 'bit' in limit:
928923
if limit['bit'] < 1e3:
929-
buf.append('%.d bps' % limit['bit'])
924+
return '%.d bps' % limit['bit']
930925
elif limit['bit'] < 1e6:
931-
buf.append('%.3f kbps' % (limit['bit'] / 1e3))
926+
return '%.3f kbps' % (limit['bit'] / 1e3)
932927
else:
933-
buf.append('%.3f Mbps' % (limit['bit'] / 1e6))
934-
935-
if buf:
936-
return 'limits: ' + ', '.join(buf)
928+
return '%.3f Mbps' % (limit['bit'] / 1e6)
937929
else:
938930
return 'unlimited'
939931

940932

933+
def _burst_to_str(burst):
934+
# no output if max_burst is not set
935+
if len(burst.values()) == 0 or burst.values()[0] == 0:
936+
return ''
937+
938+
if 'count' in burst:
939+
return 'burst: %d times' % burst['count']
940+
elif 'cycle' in burst:
941+
return 'burst: %d cycles' % burst['cycle']
942+
elif 'packet' in burst:
943+
if burst['packet'] < 1e3:
944+
return 'burst: %.d pkts' % burst['packet']
945+
elif burst['packet'] < 1e6:
946+
return 'burst: %.3f kpkts' % (burst['packet'] / 1e3)
947+
else:
948+
return 'burst: %.3f Mpkts' % (burst['packet'] / 1e6)
949+
elif 'bit' in burst:
950+
if burst['bit'] < 1e3:
951+
return 'burst: %.d bits' % burst['bit']
952+
elif burst['bit'] < 1e6:
953+
return 'burst: %.3f kbits' % (burst['bit'] / 1e3)
954+
else:
955+
return 'burst: %.3f Mbits' % (burst['bit'] / 1e6)
956+
else:
957+
return ''
958+
959+
941960
def _show_tcs_node(cli, node, indent, prefix, lastsibling):
942961
line = prefix
943962
if indent > 0:
@@ -1010,6 +1029,7 @@ def _build_tcs_tree(tcs):
10101029

10111030
if c_.policy == "rate_limit":
10121031
nodes[c_.name]["show_list"].append(_limit_to_str(c_.limit))
1032+
nodes[c_.name]["show_list"].append(_burst_to_str(c_.max_burst))
10131033

10141034
return root
10151035

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Compare worker 0 and worker 1 with "monitor tc"
2+
3+
bess.add_worker(wid=0, core=0)
4+
bess.add_worker(wid=1, core=1)
5+
dummy_pkt = '0' * 100
6+
7+
# Worker 0: no burstiness causes inaccurate scheduling
8+
w0_src0::Source() -> w0_rewrite::Rewrite(templates=[dummy_pkt]) -> Sink()
9+
w0_src1::Source() -> w0_rewrite
10+
11+
w0_src0.set_burst(burst=1)
12+
w0_src1.set_burst(burst=32)
13+
14+
bess.add_tc('w0_1000MHz', policy='rate_limit', resource='cycle', limit={'cycle': int(1e9)}, wid=0)
15+
bess.add_tc('w0_rr', policy='round_robin', parent='w0_1000MHz')
16+
bess.add_tc('w0_500MHz_0', policy='rate_limit', resource='cycle', limit={'cycle': int(0.5e9)}, parent='w0_rr')
17+
bess.add_tc('w0_500MHz_1', policy='rate_limit', resource='cycle', limit={'cycle': int(0.5e9)}, parent='w0_rr')
18+
19+
bess.attach_module(w0_src0.name, 'w0_500MHz_0')
20+
bess.attach_module(w0_src1.name, 'w0_500MHz_1')
21+
22+
# Worker 1: traffic classes with burstiness allowance
23+
w1_src0::Source() -> w1_rewrite::Rewrite(templates=[dummy_pkt]) -> Sink()
24+
w1_src1::Source() -> w1_rewrite
25+
26+
w1_src0.set_burst(burst=1)
27+
w1_src1.set_burst(burst=32)
28+
29+
bess.add_tc('w1_1000MHz', policy='rate_limit', resource='cycle', limit={'cycle': int(1e9)}, wid=1)
30+
bess.add_tc('w1_rr', policy='round_robin', parent='w1_1000MHz')
31+
bess.add_tc('w1_500MHz_0', policy='rate_limit', resource='cycle', limit={'cycle': int(0.5e9)}, max_burst={'cycle': 10000}, parent='w1_rr')
32+
bess.add_tc('w1_500MHz_1', policy='rate_limit', resource='cycle', limit={'cycle': int(0.5e9)}, max_burst={'cycle': 10000}, parent='w1_rr')
33+
34+
bess.attach_module(w1_src0.name, 'w1_500MHz_0')
35+
bess.attach_module(w1_src1.name, 'w1_500MHz_1')

core/traffic_class.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ void RateLimitTrafficClass::FinishAndAccountTowardsRoot(
465465
last_tsc_ = tsc;
466466

467467
uint64_t tokens = tokens_ + limit_ * elapsed_cycles;
468-
uint64_t consumed = usage[resource_] << USAGE_AMPLIFIER_POW;
468+
uint64_t consumed = to_work_units(usage[resource_]);
469469
if (tokens < consumed) {
470470
// Exceeded limit, throttled.
471471
tokens_ = 0;

core/traffic_class.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -438,12 +438,8 @@ class RateLimitTrafficClass final : public TrafficClass {
438438
tokens_(),
439439
last_tsc_(),
440440
child_() {
441-
limit_arg_ = limit;
442-
limit_ = to_work_units(limit);
443-
if (limit_) {
444-
max_burst_arg_ = max_burst;
445-
max_burst_ = to_work_units(max_burst);
446-
}
441+
set_limit(limit);
442+
set_max_burst(max_burst);
447443
}
448444

449445
~RateLimitTrafficClass();
@@ -482,7 +478,7 @@ class RateLimitTrafficClass final : public TrafficClass {
482478
// Set the limit to `limit`, which is in units of the resource type
483479
void set_limit(uint64_t limit) {
484480
limit_arg_ = limit;
485-
limit_ = to_work_units(limit);
481+
limit_ = to_work_units_per_cycle(limit);
486482
}
487483

488484
// Set the max burst to `burst`, which is in units of the resource type
@@ -495,9 +491,14 @@ class RateLimitTrafficClass final : public TrafficClass {
495491

496492
void TraverseChildren(std::function<void(TCChildArgs *)>) const override;
497493

494+
// Convert resource units to work units per cycle
495+
static uint64_t to_work_units_per_cycle(uint64_t x) {
496+
return (x << (USAGE_AMPLIFIER_POW - 4)) / (tsc_hz >> 4);
497+
}
498+
498499
// Convert resource units to work units
499500
static uint64_t to_work_units(uint64_t x) {
500-
return (x << (USAGE_AMPLIFIER_POW - 4)) / (tsc_hz >> 4);
501+
return x << USAGE_AMPLIFIER_POW;
501502
}
502503

503504
private:
@@ -516,8 +517,8 @@ class RateLimitTrafficClass final : public TrafficClass {
516517
// tb->limit < 2^36
517518
uint64_t limit_; // In work units per cycle (0 if unlimited).
518519
uint64_t limit_arg_; // In resource units per second.
519-
uint64_t max_burst_; // In work units per cycle (0 if unlimited).
520-
uint64_t max_burst_arg_; // In resource units per second.
520+
uint64_t max_burst_; // In work units.
521+
uint64_t max_burst_arg_; // In resource units.
521522
uint64_t tokens_; // In work units.
522523

523524
// Last time this TC was scheduled.

core/traffic_class_test.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ TEST(DefaultSchedulerNext, BasicTreeRateLimit) {
277277

278278
ASSERT_EQ(RESOURCE_COUNT, c->resource());
279279
ASSERT_EQ(50, c->limit_arg());
280-
ASSERT_EQ(RateLimitTrafficClass::to_work_units(50), c->limit());
280+
ASSERT_EQ(RateLimitTrafficClass::to_work_units_per_cycle(50), c->limit());
281281
ASSERT_EQ(100, c->max_burst_arg());
282282
ASSERT_EQ(RateLimitTrafficClass::to_work_units(100), c->max_burst());
283283

@@ -287,7 +287,8 @@ TEST(DefaultSchedulerNext, BasicTreeRateLimit) {
287287

288288
ASSERT_EQ(RESOURCE_PACKET, c->resource());
289289
ASSERT_EQ(new_limit, c->limit_arg());
290-
ASSERT_EQ(RateLimitTrafficClass::to_work_units(new_limit), c->limit());
290+
ASSERT_EQ(RateLimitTrafficClass::to_work_units_per_cycle(new_limit),
291+
c->limit());
291292
ASSERT_EQ(new_burst, c->max_burst_arg());
292293
ASSERT_EQ(RateLimitTrafficClass::to_work_units(new_burst), c->max_burst());
293294

0 commit comments

Comments
 (0)