22// vim: ts=8 sw=2 smarttab
33
44#include " Allocator.h"
5+ #include " AllocatorBase.h"
56#include < bit>
67#include " StupidAllocator.h"
78#include " BitmapAllocator.h"
@@ -21,153 +22,18 @@ using std::to_string;
2122using ceph::bufferlist;
2223using ceph::Formatter;
2324
24- class Allocator ::SocketHook : public AdminSocketHook {
25- Allocator *alloc;
2625
27- friend class Allocator ;
28- std::string name;
29- public:
30- SocketHook (Allocator *alloc, std::string_view _name) :
31- alloc (alloc), name(_name)
32- {
33- AdminSocket *admin_socket = g_ceph_context->get_admin_socket ();
34- if (name.empty ()) {
35- name = to_string ((uintptr_t )this );
36- }
37- if (admin_socket) {
38- int r = admin_socket->register_command (
39- (" bluestore allocator dump " + name).c_str (),
40- this ,
41- " dump allocator free regions" );
42- if (r != 0 )
43- alloc = nullptr ; // some collision, disable
44- if (alloc) {
45- r = admin_socket->register_command (
46- (" bluestore allocator score " + name).c_str (),
47- this ,
48- " give score on allocator fragmentation (0-no fragmentation, 1-absolute fragmentation)" );
49- ceph_assert (r == 0 );
50- r = admin_socket->register_command (
51- (" bluestore allocator fragmentation " + name).c_str (),
52- this ,
53- " give allocator fragmentation (0-no fragmentation, 1-absolute fragmentation)" );
54- ceph_assert (r == 0 );
55- r = admin_socket->register_command (
56- (" bluestore allocator fragmentation histogram " + name +
57- " name=alloc_unit,type=CephInt,req=false" +
58- " name=num_buckets,type=CephInt,req=false" ).c_str (),
59- this ,
60- " build allocator free regions state histogram" );
61- ceph_assert (r == 0 );
62- }
63- }
64- }
65- ~SocketHook ()
66- {
67- AdminSocket *admin_socket = g_ceph_context->get_admin_socket ();
68- if (admin_socket && alloc) {
69- admin_socket->unregister_commands (this );
70- }
71- }
72-
73- int call (std::string_view command,
74- const cmdmap_t & cmdmap,
75- const bufferlist&,
76- Formatter *f,
77- std::ostream& ss,
78- bufferlist& out) override {
79- int r = 0 ;
80- if (command == " bluestore allocator dump " + name) {
81- f->open_object_section (" allocator_dump" );
82- f->dump_unsigned (" capacity" , alloc->get_capacity ());
83- f->dump_unsigned (" alloc_unit" , alloc->get_block_size ());
84- f->dump_string (" alloc_type" , alloc->get_type ());
85- f->dump_string (" alloc_name" , name);
86-
87- f->open_array_section (" extents" );
88- auto iterated_allocation = [&](size_t off, size_t len) {
89- ceph_assert (len > 0 );
90- f->open_object_section (" free" );
91- char off_hex[30 ];
92- char len_hex[30 ];
93- snprintf (off_hex, sizeof (off_hex) - 1 , " 0x%zx" , off);
94- snprintf (len_hex, sizeof (len_hex) - 1 , " 0x%zx" , len);
95- f->dump_string (" offset" , off_hex);
96- f->dump_string (" length" , len_hex);
97- f->close_section ();
98- };
99- alloc->foreach (iterated_allocation);
100- f->close_section ();
101- f->close_section ();
102- } else if (command == " bluestore allocator score " + name) {
103- f->open_object_section (" fragmentation_score" );
104- f->dump_float (" fragmentation_rating" , alloc->get_fragmentation_score ());
105- f->close_section ();
106- } else if (command == " bluestore allocator fragmentation " + name) {
107- f->open_object_section (" fragmentation" );
108- f->dump_float (" fragmentation_rating" , alloc->get_fragmentation ());
109- f->close_section ();
110- } else if (command == " bluestore allocator fragmentation histogram " + name) {
111- int64_t alloc_unit = alloc->get_block_size ();
112- cmd_getval (cmdmap, " alloc_unit" , alloc_unit);
113- if (alloc_unit <= 0 ||
114- p2align (alloc_unit, alloc->get_block_size ()) != alloc_unit) {
115- ss << " Invalid allocation unit: '" << alloc_unit
116- << " ', to be aligned with: '" << alloc->get_block_size ()
117- << " '" << std::endl;
118- return -EINVAL;
119- }
120- int64_t num_buckets = 8 ;
121- cmd_getval (cmdmap, " num_buckets" , num_buckets);
122- if (num_buckets < 2 ) {
123- ss << " Invalid amount of buckets (min=2): '" << num_buckets
124- << " '" << std::endl;
125- return -EINVAL;
126- }
127-
128- Allocator::FreeStateHistogram hist (num_buckets);
129- alloc->foreach (
130- [&](size_t off, size_t len) {
131- hist.record_extent (uint64_t (alloc_unit), off, len);
132- });
133- f->open_array_section (" extent_counts" );
134- hist.foreach (
135- [&](uint64_t max_len, uint64_t total, uint64_t aligned, uint64_t units) {
136- f->open_object_section (" c" );
137- f->dump_unsigned (" max_len" , max_len);
138- f->dump_unsigned (" total" , total);
139- f->dump_unsigned (" aligned" , aligned);
140- f->dump_unsigned (" units" , units);
141- f->close_section ();
142- }
143- );
144- f->close_section ();
145- } else {
146- ss << " Invalid command" << std::endl;
147- r = -ENOSYS;
148- }
149- return r;
150- }
151-
152- };
15326Allocator::Allocator (std::string_view name,
15427 int64_t _capacity,
15528 int64_t _block_size)
15629 : device_size(_capacity),
15730 block_size(_block_size)
158- {
159- asok_hook = new SocketHook (this , name);
160- }
31+ {}
16132
16233
16334Allocator::~Allocator ()
164- {
165- delete asok_hook;
166- }
35+ {}
16736
168- const string& Allocator::get_name () const {
169- return asok_hook->name ;
170- }
17137
17238Allocator *Allocator::create (
17339 CephContext* cct,
@@ -275,40 +141,3 @@ double Allocator::get_fragmentation_score()
275141 return (ideal - score_sum) / (ideal - terrible);
276142}
277143
278- /* ************
279- * Allocator::FreeStateHistogram
280- *************/
281- using std::function;
282-
283- void Allocator::FreeStateHistogram::record_extent (uint64_t alloc_unit,
284- uint64_t off,
285- uint64_t len)
286- {
287- size_t idx = myTraits._get_bucket (len);
288- ceph_assert (idx < buckets.size ());
289- ++buckets[idx].total ;
290-
291- // now calculate the bucket for the chunk after alignment,
292- // resulting chunks shorter than alloc_unit are discarded
293- auto delta = p2roundup (off, alloc_unit) - off;
294- if (len >= delta + alloc_unit) {
295- len -= delta;
296- idx = myTraits._get_bucket (len);
297- ceph_assert (idx < buckets.size ());
298- ++buckets[idx].aligned ;
299- buckets[idx].alloc_units += len / alloc_unit;
300- }
301- }
302- void Allocator::FreeStateHistogram::foreach (
303- function<void (uint64_t max_len,
304- uint64_t total,
305- uint64_t aligned,
306- uint64_t unit)> cb)
307- {
308- size_t i = 0 ;
309- for (const auto & b : buckets) {
310- cb (myTraits._get_bucket_max (i),
311- b.total , b.aligned , b.alloc_units );
312- ++i;
313- }
314- }
0 commit comments