Motr  M0
ag.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CM
24 #include "lib/trace.h"
25 
26 #include "lib/string.h" /* memcpy */
27 #include "lib/misc.h"
28 #include "lib/errno.h"
29 
30 #include "motr/magic.h"
31 
32 #include "cm/sw.h"
33 #include "cm/proxy.h"
34 #include "cm/ag.h"
35 #include "cm/cm.h"
36 #include "cm/cp.h"
37 
42 M0_TL_DESCR_DEFINE(aggr_grps_in, "aggregation groups incoming", M0_INTERNAL,
43  struct m0_cm_aggr_group, cag_cm_in_linkage, cag_magic,
45 
46 M0_TL_DEFINE(aggr_grps_in, M0_INTERNAL, struct m0_cm_aggr_group);
47 
48 M0_TL_DESCR_DEFINE(aggr_grps_out, "aggregation groups outgoing", M0_INTERNAL,
49  struct m0_cm_aggr_group, cag_cm_out_linkage, cag_magic,
51 
52 M0_TL_DEFINE(aggr_grps_out, M0_INTERNAL, struct m0_cm_aggr_group);
53 
55 
57 
58 M0_INTERNAL void m0_cm_ag_lock(struct m0_cm_aggr_group *ag)
59 {
61 }
62 
63 M0_INTERNAL void m0_cm_ag_unlock(struct m0_cm_aggr_group *ag)
64 {
66 }
67 
68 M0_INTERNAL bool m0_cm_ag_is_locked(struct m0_cm_aggr_group *ag)
69 {
70  return m0_mutex_is_locked(&ag->cag_mutex);
71 }
72 
73 M0_INTERNAL int m0_cm_ag_id_cmp(const struct m0_cm_ag_id *id0,
74  const struct m0_cm_ag_id *id1)
75 {
76  M0_PRE(id0 != NULL);
77  M0_PRE(id1 != NULL);
78 
79  return m0_uint128_cmp(&id0->ai_hi, &id1->ai_hi) ?:
80  m0_uint128_cmp(&id0->ai_lo, &id1->ai_lo);
81 }
82 
83 M0_INTERNAL void m0_cm_ag_id_copy(struct m0_cm_ag_id *dst,
84  const struct m0_cm_ag_id *src)
85 {
86  M0_PRE(dst != NULL);
87  M0_PRE(src != NULL);
88 
89  dst->ai_hi.u_hi = src->ai_hi.u_hi;
90  dst->ai_hi.u_lo = src->ai_hi.u_lo;
91  dst->ai_lo.u_hi = src->ai_lo.u_hi;
92  dst->ai_lo.u_lo = src->ai_lo.u_lo;
93 }
94 
95 M0_INTERNAL bool m0_cm_ag_id_is_set(const struct m0_cm_ag_id *id)
96 {
97  struct m0_cm_ag_id id0;
98 
99  M0_SET0(&id0);
100 
101  return m0_cm_ag_id_cmp(id, &id0) != 0;
102 }
103 
104 static void _fini_ast_cb(struct m0_sm_group *grp, struct m0_sm_ast *ast)
105 {
106  struct m0_cm_aggr_group *ag = M0_AMB(ag, ast, cag_fini_ast);
107  struct m0_cm *cm = ag->cag_cm;
108  struct m0_cm_aggr_group *in;
109  struct m0_cm_aggr_group *out;
110  struct m0_cm_ag_store *agstore;
111  bool has_incoming;
112 
113  has_incoming = ag->cag_has_incoming;
114 
115 
116  /* m0_cm_aggr_group:cag_fini_ast is posted with ag lock held
117  * in m0_cm::cm_sm_group, posted ast can be immediately picked
118  * for execution in context of m0_cm_{lock, unlock}. Here we
119  * acquire m0_cm_ag_lock and release it to make sure its not
120  * held during its finalisation.
121  */
122  m0_cm_ag_lock(ag);
123  m0_cm_ag_unlock(ag);
124 
125  /*
126  * Update m0_cm::cm_store to persist lowest aggregation group in
127  * sliding window and out going groups.
128  */
129 
130  agstore = &cm->cm_ag_store;
131  if (ag->cag_rc == 0 && !ag->cag_is_frozen) {
132  if (has_incoming) {
133  in = aggr_grps_in_tlist_head(&cm->cm_aggr_grps_in);
134  if (in != NULL) {
135  if (m0_cm_ag_id_cmp(&in->cag_id,
136  &ag->cag_id) == 0)
137  agstore->s_data.d_in = ag->cag_id;
138  }
139  } else {
140  out = aggr_grps_out_tlist_head(&cm->cm_aggr_grps_out);
141  if (out != NULL) {
142  if (m0_cm_ag_id_cmp(&out->cag_id,
143  &ag->cag_id) == 0)
144  agstore->s_data.d_out = ag->cag_id;
145  }
146  }
147 
148  agstore->s_data.d_cm_epoch = cm->cm_epoch;
149  }
150  ag->cag_ops->cago_fini(ag);
151 }
152 
153 M0_INTERNAL void m0_cm_aggr_group_init(struct m0_cm_aggr_group *ag,
154  struct m0_cm *cm,
155  const struct m0_cm_ag_id *id,
156  bool has_incoming,
157  const struct m0_cm_aggr_group_ops
158  *ag_ops)
159 {
160  M0_ENTRY();
161  M0_PRE(id != NULL);
162  M0_PRE(cm != NULL);
163  M0_PRE(ag != NULL);
164  M0_PRE(ag_ops != NULL);
166 
167  ag->cag_cm = cm;
168  m0_mutex_init(&ag->cag_mutex);
169  ag->cag_id = *id;
170  ag->cag_has_incoming = has_incoming;
171  aggr_grps_in_tlink_init(ag);
172  aggr_grps_out_tlink_init(ag);
173  ag->cag_ops = ag_ops;
175  ag->cag_ref = 0;
177  M0_LEAVE();
178 }
179 
180 M0_INTERNAL void m0_cm_aggr_group_fini(struct m0_cm_aggr_group *ag)
181 {
182  struct m0_cm *cm;
183 
184  M0_ENTRY();
185  M0_ASSERT(ag != NULL);
186 
187  cm = ag->cag_cm;
189  if (aggr_grps_in_tlink_is_in(ag)) {
190  aggr_grps_in_tlist_del(ag);
192  M0_LOG(M0_DEBUG, "cm %p, DEC in_nr %"PRIu64, cm, cm->cm_aggr_grps_in_nr);
193  }
194  aggr_grps_in_tlink_fini(ag);
195  if (aggr_grps_out_tlink_is_in(ag)) {
196  aggr_grps_out_tlist_del(ag);
198  M0_LOG(M0_DEBUG, "cm %p, DEC out_nr %"PRIu64, cm, cm->cm_aggr_grps_out_nr);
199  }
200  aggr_grps_out_tlink_fini(ag);
201  M0_POST(!aggr_grps_in_tlink_is_in(ag) &&
202  !aggr_grps_out_tlink_is_in(ag));
203  m0_mutex_fini(&ag->cag_mutex);
204  M0_LEAVE();
205 }
206 
208 {
209  struct m0_cm *cm;
210  struct m0_cm_ag_id id;
211  struct m0_cm_aggr_group *hi;
212  struct m0_cm_aggr_group *lo;
213  int rc;
214 
215  M0_ENTRY("ag: %p", ag);
216  M0_ASSERT(ag != NULL);
217 
218  cm = ag->cag_cm;
220  id = ag->cag_id;
221  hi = m0_cm_ag_in_hi(cm);
222  lo = m0_cm_ag_in_lo(cm);
223 
224  rc = ag->cag_rc;
225  ID_INCOMING_LOG("id", &id, ag->cag_has_incoming);
226  if (lo != NULL && hi != NULL) {
227  ID_LOG("lo", &lo->cag_id);
228  ID_LOG("hi", &hi->cag_id);
229  }
231 
234 
235  M0_LOG(M0_DEBUG, "%" PRId64 ": ["M0_AG_F"] "
236  "in=[%" PRId64 "] out=[%" PRId64 "] rc: %d",
239 
240  M0_LEAVE();
241 }
242 
243 static struct m0_cm_aggr_group *
245  const struct m0_tl_descr *descr,
246  struct m0_tl *head)
247 {
248  struct m0_cm_aggr_group *ag;
249 
250  m0_tlist_for(descr, head, ag) {
251  if (m0_cm_ag_id_cmp(id, &ag->cag_id) == 0) {
252  M0_LEAVE("Found ag: %p", ag);
253  return ag;
254  }
255  } m0_tlist_endfor;
256 
257  M0_LEAVE("ag not found");
258  return NULL;
259 }
260 
261 M0_INTERNAL struct m0_cm_aggr_group *
262 m0_cm_aggr_group_locate(struct m0_cm *cm, const struct m0_cm_ag_id *id,
263  bool has_incoming)
264 {
265  struct m0_cm_aggr_group *ag;
266 
267  M0_ENTRY("cm: %p", cm);
268  M0_PRE(cm != NULL);
270 
271  ID_INCOMING_LOG("id", id, has_incoming);
272  if (has_incoming) {
273  ag = __aggr_group_locate(id, &aggr_grps_in_tl,
274  &cm->cm_aggr_grps_in);
275  } else {
276  ag = __aggr_group_locate(id, &aggr_grps_out_tl,
277  &cm->cm_aggr_grps_out);
278  }
279  return ag;
280 }
281 
282 static void __aggr_group_add(struct m0_cm_aggr_group *ag,
283  const struct m0_tl_descr *descr,
284  struct m0_tl *head)
285 {
286  struct m0_cm_aggr_group *found;
287  int val;
288 
289  m0_tlist_for(descr, head, found) {
290  val = m0_cm_ag_id_cmp(&ag->cag_id, &found->cag_id);
291  M0_ASSERT(val != 0);
292  if (val < 0) {
293  m0_tlist_add_before(descr, found, ag);
294  M0_LEAVE();
295  return;
296  }
297  } m0_tl_endfor;
298  m0_tlist_add_tail(descr, head, ag);
299 }
300 
301 M0_INTERNAL void m0_cm_aggr_group_add(struct m0_cm *cm,
302  struct m0_cm_aggr_group *ag,
303  bool has_incoming)
304 {
305  struct m0_cm_ag_id id = ag->cag_id;
306 
307  M0_ENTRY("cm: %p, ag: %p", cm, ag);
308  M0_PRE(cm != NULL);
309  M0_PRE(ag != NULL);
311 
312  ID_INCOMING_LOG("id", &id, has_incoming);
313  if (has_incoming) {
314  __aggr_group_add(ag, &aggr_grps_in_tl, &cm->cm_aggr_grps_in);
316  M0_LOG(M0_DEBUG,"cm %p, INC in_nr %"PRIu64, cm, cm->cm_aggr_grps_in_nr);
317  if (m0_cm_ag_id_cmp(&cm->cm_sw_last_updated_hi, &id) < 0)
319  } else {
320  __aggr_group_add(ag, &aggr_grps_out_tl, &cm->cm_aggr_grps_out);
322  M0_LOG(M0_DEBUG,"cm %p, INC out_nr %"PRIu64, cm, cm->cm_aggr_grps_out_nr);
323  if (m0_cm_ag_id_cmp(&cm->cm_last_out_hi, &id) < 0)
324  cm->cm_last_out_hi = id;
325  }
326 
327  M0_LEAVE();
328 }
329 
330 M0_INTERNAL int m0_cm_aggr_group_alloc(struct m0_cm *cm,
331  const struct m0_cm_ag_id *id,
332  bool has_incoming,
333  struct m0_cm_aggr_group **out)
334 {
335  int rc;
336 
337  M0_ENTRY("cm: %p", cm);
338  M0_PRE(cm != NULL && id != NULL);
340 
341  ID_INCOMING_LOG("id", id, has_incoming);
342  ID_LOG("last_saved_id", &cm->cm_sw_last_updated_hi);
343 
344  rc = cm->cm_ops->cmo_ag_alloc(cm, id, has_incoming, out);
345  M0_ASSERT(rc <= 0);
346  if (rc == 0 || rc == -ENOBUFS)
347  m0_cm_aggr_group_add(cm, *out, has_incoming);
348  else if (rc != 0)
349  return M0_RC(rc);
350 
351  M0_ASSERT(rc <= 0);
352  return M0_RC(rc);
353 }
354 
355 M0_INTERNAL bool m0_cm_aggr_group_tlists_are_empty(struct m0_cm *cm)
356 {
357  struct m0_cm_ag_id grp_end_mark_id = GRP_END_MARK_ID;
358 
359  M0_LOG(M0_DEBUG, "cm=%p ag_in_nr=%" PRIu64 " ag_out_nr=%"PRIu64
360  " m0_cm_ag_in_hi(cm)=%p",
363 
364  /* For DIX cm, always has a GRP_END_MARK_ID in its incoming list */
365  if (m0_cm_ag_in_hi(cm) != NULL)
366  M0_LOG(M0_DEBUG, "m0_cm_ag_in_hi(cm)->cag_id="M0_AG_F,
367  M0_AG_P(&m0_cm_ag_in_hi(cm)->cag_id));
368 
369  return (cm->cm_aggr_grps_in_nr == 0 ||
370  (cm->cm_aggr_grps_in_nr == 1 &&
372  &grp_end_mark_id) == 0)
373  ) &&
374  cm->cm_aggr_grps_out_nr == 0;
375 }
376 
377 M0_INTERNAL int m0_cm_ag_advance(struct m0_cm *cm)
378 {
379  struct m0_cm_ag_id next;
380  struct m0_cm_ag_id id;
381  int rc;
382 
383  M0_ENTRY();
384 
386 
387  M0_SET0(&id);
388  M0_SET0(&next);
390  do {
391  ID_LOG("id", &id);
392  rc = cm->cm_ops->cmo_ag_next(cm, &id, &next);
393  M0_LOG(M0_DEBUG, "next ["M0_AG_F"] rc=%d", M0_AG_P(&next), rc);
394  if (rc == 0 && m0_cm_ag_id_is_set(&next)) {
395  id = next;
396  M0_SET0(&next);
397  }
398  } while (rc == 0);
399 
400  return M0_RC(rc);
401 }
402 
403 M0_INTERNAL struct m0_cm_aggr_group *m0_cm_ag_in_hi(const struct m0_cm *cm)
404 {
405 
406  M0_PRE(cm != NULL);
408 
409  return aggr_grps_in_tlist_tail(&cm->cm_aggr_grps_in);
410 }
411 
412 M0_INTERNAL struct m0_cm_aggr_group *m0_cm_ag_in_lo(const struct m0_cm *cm)
413 {
414  M0_PRE(cm != NULL);
416 
417  return aggr_grps_in_tlist_head(&cm->cm_aggr_grps_in);
418 }
419 
420 M0_INTERNAL struct m0_cm_aggr_group *m0_cm_ag_out_lo(const struct m0_cm *cm)
421 {
422  M0_PRE(cm != NULL);
424 
425  return aggr_grps_out_tlist_head(&cm->cm_aggr_grps_out);
426 }
427 
428 M0_INTERNAL struct m0_cm_aggr_group *m0_cm_ag_out_hi(const struct m0_cm *cm)
429 {
430  M0_PRE(cm != NULL);
432 
433  return aggr_grps_out_tlist_tail(&cm->cm_aggr_grps_out);
434 }
435 
436 M0_INTERNAL void m0_cm_ag_in_interval(const struct m0_cm *cm,
437  struct m0_cm_sw *in_interval)
438 {
439  struct m0_cm_aggr_group *ag;
440 
442  M0_PRE(in_interval != NULL);
443 
444  M0_SET0(&in_interval->sw_lo);
445  M0_SET0(&in_interval->sw_hi);
446  ag = m0_cm_ag_in_hi(cm);
447  if (ag != NULL)
448  m0_cm_ag_id_copy(&in_interval->sw_hi, &ag->cag_id);
449  ag = m0_cm_ag_in_lo(cm);
450  if (ag != NULL)
451  m0_cm_ag_id_copy(&in_interval->sw_lo, &ag->cag_id);
452 }
453 
454 M0_INTERNAL void m0_cm_ag_out_interval(const struct m0_cm *cm,
455  struct m0_cm_sw *out_interval)
456 {
457  struct m0_cm_aggr_group *ag;
458 
460  M0_PRE(out_interval != NULL);
461 
462  M0_SET0(&out_interval->sw_lo);
463  M0_SET0(&out_interval->sw_hi);
464  ag = m0_cm_ag_out_hi(cm);
465  if (ag != NULL)
466  m0_cm_ag_id_copy(&out_interval->sw_hi, &ag->cag_id);
467  ag = m0_cm_ag_out_lo(cm);
468  if (ag != NULL)
469  m0_cm_ag_id_copy(&out_interval->sw_lo, &ag->cag_id);
470 }
471 
472 static void cm_ag_get(struct m0_cm_aggr_group *ag)
473 {
475 
476  M0_CNT_INC(ag->cag_ref);
477 }
478 
479 static void cm_ag_put(struct m0_cm_aggr_group *ag)
480 {
482 
483  M0_CNT_DEC(ag->cag_ref);
484  if ((ag->cag_ref == 0 || ag->cag_is_frozen || ag->cag_rc != 0) && m0_cm_ag_can_fini(ag))
485  m0_cm_ag_fini_post(ag);
486 }
487 
488 M0_INTERNAL void m0_cm_ag_get(struct m0_cm_aggr_group *ag)
489 {
490  m0_cm_ag_lock(ag);
491  cm_ag_get(ag);
492  m0_cm_ag_unlock(ag);
493 }
494 
495 M0_INTERNAL void m0_cm_ag_put(struct m0_cm_aggr_group *ag)
496 {
497  m0_cm_ag_lock(ag);
498  cm_ag_put(ag);
499  m0_cm_ag_unlock(ag);
500 }
501 
502 M0_INTERNAL void m0_cm_ag_cp_add_locked(struct m0_cm_aggr_group *ag, struct m0_cm_cp *cp)
503 {
505 
506  cp->c_ag = ag;
507  cm_ag_get(ag);
508 }
509 
510 M0_INTERNAL void m0_cm_ag_cp_add(struct m0_cm_aggr_group *ag, struct m0_cm_cp *cp)
511 {
512  M0_PRE(ag != NULL);
513  M0_PRE(cp != NULL);
514 
515  m0_cm_ag_lock(ag);
516  m0_cm_ag_cp_add_locked(ag, cp);
517  m0_cm_ag_unlock(ag);
518 }
519 
520 M0_INTERNAL void m0_cm_ag_cp_del(struct m0_cm_aggr_group *ag, struct m0_cm_cp *cp)
521 {
522  M0_PRE(ag != NULL);
523  M0_PRE(cp != NULL);
524 
525  m0_cm_ag_lock(ag);
526  if (cp->c_rc != 0)
527  ag->cag_rc = cp->c_rc;
529  cm_ag_put(ag);
530  m0_cm_ag_unlock(ag);
531 }
532 
533 M0_INTERNAL void m0_cm_ag_fini_post(struct m0_cm_aggr_group *ag)
534 {
536 }
537 
538 M0_INTERNAL bool m0_cm_ag_can_fini(struct m0_cm_aggr_group *ag)
539 {
541 
542  if (ag->cag_ops->cago_ag_can_fini(ag) && !ag->cag_is_finalising) {
543  ag->cag_is_finalising = true;
544  return true;
545  }
546 
547  return false;
548 }
549 
551 #undef M0_TRACE_SUBSYSTEM
552 
553 /*
554  * Local variables:
555  * c-indentation-style: "K&R"
556  * c-basic-offset: 8
557  * tab-width: 8
558  * fill-column: 79
559  * scroll-step: 1
560  * End:
561  */
M0_INTERNAL int m0_uint128_cmp(const struct m0_uint128 *u0, const struct m0_uint128 *u1)
Definition: misc.c:45
M0_INTERNAL void m0_cm_ag_id_copy(struct m0_cm_ag_id *dst, const struct m0_cm_ag_id *src)
Definition: ag.c:83
uint64_t cm_aggr_grps_in_nr
Definition: cm.h:205
uint64_t id
Definition: cob.h:2380
M0_INTERNAL struct m0_cm_aggr_group * m0_cm_ag_out_lo(const struct m0_cm *cm)
Definition: ag.c:420
M0_INTERNAL void m0_cm_ag_unlock(struct m0_cm_aggr_group *ag)
Definition: ag.c:63
int(* cmo_ag_alloc)(struct m0_cm *cm, const struct m0_cm_ag_id *id, bool has_incoming, struct m0_cm_aggr_group **out)
Definition: cm.h:306
M0_INTERNAL void m0_cm_ag_get(struct m0_cm_aggr_group *ag)
Definition: ag.c:488
#define M0_PRE(cond)
M0_INTERNAL struct m0_cm_aggr_group * m0_cm_ag_out_hi(const struct m0_cm *cm)
Definition: ag.c:428
M0_INTERNAL void m0_cm_ag_cp_del(struct m0_cm_aggr_group *ag, struct m0_cm_cp *cp)
Definition: ag.c:520
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
Definition: sw.h:45
#define NULL
Definition: misc.h:38
#define M0_AG_P(ag)
Definition: ag.h:55
M0_INTERNAL bool m0_cm_ag_can_fini(struct m0_cm_aggr_group *ag)
Definition: ag.c:538
#define ID_LOG(prefix, id)
Definition: ag.h:57
static struct m0_bufvec dst
Definition: xform.c:61
Definition: idx_mock.c:52
void(* sa_cb)(struct m0_sm_group *grp, struct m0_sm_ast *)
Definition: sm.h:506
const struct m0_cm_ops * cm_ops
Definition: cm.h:188
struct m0_cm_ag_id sw_hi
Definition: sw.h:47
M0_INTERNAL void m0_cm_aggr_group_add(struct m0_cm *cm, struct m0_cm_aggr_group *ag, bool has_incoming)
Definition: ag.c:301
static struct m0_sm_group * grp
Definition: bytecount.c:38
#define M0_LOG(level,...)
Definition: trace.h:167
Definition: cp.h:160
M0_LEAVE()
M0_INTERNAL void m0_tlist_add_before(const struct m0_tl_descr *d, void *obj, void *new)
Definition: tlist.c:149
M0_INTERNAL void m0_sm_ast_post(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: sm.c:135
void(* cago_fini)(struct m0_cm_aggr_group *ag)
Definition: ag.h:140
uint64_t cm_id
Definition: cm.h:174
static void __aggr_group_add(struct m0_cm_aggr_group *ag, const struct m0_tl_descr *descr, struct m0_tl *head)
Definition: ag.c:282
struct m0_cm_ag_id d_out
Definition: ag_store.h:46
M0_INTERNAL struct m0_cm_aggr_group * m0_cm_ag_in_hi(const struct m0_cm *cm)
Definition: ag.c:403
struct m0_cm_ag_id cag_id
Definition: ag.h:72
M0_BOB_DEFINE(static M0_UNUSED, &ag_bob, m0_cm_aggr_group)
struct m0_bob_type ag_bob
Definition: ag.c:54
M0_INTERNAL void m0_cm_ag_in_interval(const struct m0_cm *cm, struct m0_cm_sw *in_interval)
Definition: ag.c:436
int(* cmo_ag_next)(struct m0_cm *cm, const struct m0_cm_ag_id *id_curr, struct m0_cm_ag_id *id_next)
Definition: cm.h:324
Definition: sm.h:504
uint64_t cm_aggr_grps_out_nr
Definition: cm.h:233
#define M0_SET0(obj)
Definition: misc.h:64
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
M0_INTERNAL bool m0_cm_ag_id_is_set(const struct m0_cm_ag_id *id)
Definition: ag.c:95
uint64_t(* cago_local_cp_nr)(const struct m0_cm_aggr_group *ag)
Definition: ag.h:146
M0_INTERNAL void m0_cm_aggr_group_init(struct m0_cm_aggr_group *ag, struct m0_cm *cm, const struct m0_cm_ag_id *id, bool has_incoming, const struct m0_cm_aggr_group_ops *ag_ops)
Definition: ag.c:153
#define m0_tl_endfor
Definition: tlist.h:700
static struct m0_uint128 id0[UPDATE_NR *DTM_NR]
Definition: dtx.c:57
return M0_RC(rc)
static struct m0_cm * cm
Definition: cm.c:63
static int head(struct m0_sm *mach)
Definition: sm.c:468
#define M0_ENTRY(...)
Definition: trace.h:170
bool cag_is_frozen
Definition: ag.h:106
static struct m0_sm_ast ast[NR]
Definition: locality.c:44
M0_INTERNAL void m0_cm_ag_cp_add(struct m0_cm_aggr_group *ag, struct m0_cm_cp *cp)
Definition: ag.c:510
#define M0_AG_F
Definition: ag.h:54
M0_INTERNAL void m0_cm_complete_notify(struct m0_cm *cm)
Definition: cm.c:1133
static struct m0_cm_aggr_group * __aggr_group_locate(const struct m0_cm_ag_id *id, const struct m0_tl_descr *descr, struct m0_tl *head)
Definition: ag.c:244
#define PRIu64
Definition: types.h:58
M0_INTERNAL bool m0_cm_ag_is_locked(struct m0_cm_aggr_group *ag)
Definition: ag.c:68
M0_INTERNAL void m0_cm_ag_lock(struct m0_cm_aggr_group *ag)
Definition: ag.c:58
int cag_rc
Definition: ag.h:126
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
M0_INTERNAL int m0_cm_ag_id_cmp(const struct m0_cm_ag_id *id0, const struct m0_cm_ag_id *id1)
Definition: ag.c:73
#define M0_ASSERT(cond)
M0_INTERNAL bool m0_mutex_is_locked(const struct m0_mutex *mutex)
Definition: mutex.c:95
int c_rc
Definition: cp.h:218
M0_INTERNAL void m0_cm_ag_put(struct m0_cm_aggr_group *ag)
Definition: ag.c:495
Definition: tlist.h:251
struct m0_cm * cag_cm
Definition: ag.h:70
static void cm_ag_put(struct m0_cm_aggr_group *ag)
Definition: ag.c:479
uint64_t cag_ref
Definition: ag.h:80
static int next[]
Definition: cp.c:248
M0_INTERNAL struct m0_cm_aggr_group * m0_cm_aggr_group_locate(struct m0_cm *cm, const struct m0_cm_ag_id *id, bool has_incoming)
Definition: ag.c:262
M0_TL_DESCR_DEFINE(aggr_grps_in, "aggregation groups incoming", M0_INTERNAL, struct m0_cm_aggr_group, cag_cm_in_linkage, cag_magic, CM_AG_LINK_MAGIX, CM_AG_HEAD_MAGIX)
struct m0_cm_ag_id sw_lo
Definition: sw.h:46
M0_INTERNAL struct m0_cm_aggr_group * m0_cm_ag_in_lo(const struct m0_cm *cm)
Definition: ag.c:412
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
#define M0_POST(cond)
struct m0_cm_ag_id cm_last_out_hi
Definition: cm.h:222
bool cag_is_finalising
Definition: ag.h:103
struct m0_cm_aggr_group * c_ag
Definition: cp.h:172
struct m0_sm_ast cag_fini_ast
Definition: ag.h:78
static void cm_ag_get(struct m0_cm_aggr_group *ag)
Definition: ag.c:472
#define PRId64
Definition: types.h:57
M0_TL_DEFINE(aggr_grps_in, M0_INTERNAL, struct m0_cm_aggr_group)
struct m0_sm_group cm_sm_group
Definition: cm.h:185
#define ID_INCOMING_LOG(prefix, id, has_incoming)
Definition: ag.h:58
struct m0_tl cm_aggr_grps_out
Definition: cm.h:231
#define GRP_END_MARK_ID
Definition: ag.h:62
#define M0_CNT_INC(cnt)
Definition: arith.h:226
uint64_t cag_freed_cp_nr
Definition: ag.h:98
M0_INTERNAL void m0_cm_aggr_group_fini(struct m0_cm_aggr_group *ag)
Definition: ag.c:180
struct m0_cm_ag_store_data s_data
Definition: ag_store.h:52
const struct m0_cm_aggr_group_ops * cag_ops
Definition: ag.h:74
M0_INTERNAL void m0_cm_ag_out_interval(const struct m0_cm *cm, struct m0_cm_sw *out_interval)
Definition: ag.c:454
M0_INTERNAL int m0_cm_ag_advance(struct m0_cm *cm)
Definition: ag.c:377
Definition: cm.h:166
M0_INTERNAL bool m0_cm_aggr_group_tlists_are_empty(struct m0_cm *cm)
Definition: ag.c:355
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
uint64_t cag_cp_local_nr
Definition: ag.h:92
#define m0_tlist_endfor
Definition: tlist.h:448
struct m0_uint128 ai_hi
Definition: ag.h:50
struct m0_uint128 ai_lo
Definition: ag.h:51
M0_INTERNAL void m0_cm_ag_fini_post(struct m0_cm_aggr_group *ag)
Definition: ag.c:533
struct m0_mutex cag_mutex
Definition: ag.h:76
#define M0_CNT_DEC(cnt)
Definition: arith.h:219
static uint64_t found
Definition: base.c:376
M0_INTERNAL int m0_cm_aggr_group_alloc(struct m0_cm *cm, const struct m0_cm_ag_id *id, bool has_incoming, struct m0_cm_aggr_group **out)
Definition: ag.c:330
bool cag_has_incoming
Definition: ag.h:101
#define m0_tlist_for(descr, head, obj)
Definition: tlist.h:435
#define out(...)
Definition: gen.c:41
static void _fini_ast_cb(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: ag.c:104
bool(* cago_ag_can_fini)(const struct m0_cm_aggr_group *ag)
Definition: ag.h:137
struct m0_tl cm_aggr_grps_in
Definition: cm.h:203
M0_INTERNAL bool m0_cm_is_locked(const struct m0_cm *cm)
Definition: cm.c:560
M0_INTERNAL void m0_cm_ag_cp_add_locked(struct m0_cm_aggr_group *ag, struct m0_cm_cp *cp)
Definition: ag.c:502
struct m0_pdclust_src_addr src
Definition: fd.c:108
int32_t rc
Definition: trigger_fop.h:47
static void hi(void)
Definition: nucleus.c:93
struct m0_cm_ag_id d_in
Definition: ag_store.h:45
m0_time_t d_cm_epoch
Definition: ag_store.h:47
M0_INTERNAL void m0_tlist_add_tail(const struct m0_tl_descr *d, struct m0_tl *list, void *obj)
Definition: tlist.c:133
m0_time_t cm_epoch
Definition: cm.h:177
Definition: ag.h:49
M0_INTERNAL void m0_cm_aggr_group_fini_and_progress(struct m0_cm_aggr_group *ag)
Definition: ag.c:207
struct m0_cm_ag_store cm_ag_store
Definition: cm.h:261
struct m0_cm_ag_id cm_sw_last_updated_hi
Definition: cm.h:220
#define M0_UNUSED
Definition: misc.h:380