Motr  M0
perf.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2019-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_STOB
24 #include "lib/trace.h"
25 
26 #include "stob/perf.h"
27 
28 #include <sys/mount.h> /* mount */
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #include <stdio.h> /* FILE, fopen */
32 #include <unistd.h> /* rmdir */
33 
34 #include "lib/errno.h"
35 #include "lib/locality.h" /* m0_locality_get */
36 #include "lib/memory.h"
37 #include "lib/string.h" /* m0_strdup */
38 #include "lib/timer.h" /* m0_timer */
39 #include "stob/type.h"
40 #include "stob/domain.h"
41 #include "stob/io.h"
42 #include "stob/stob.h"
43 
105 struct stob_perf_io;
106 
108 
114 };
115 
121  uint64_t spd_magic;
122 };
123 
124 /* XXX TODO populate with stats and store it to tmpfs periodically or on stob
125  * finalisation */
127  int unused;
128 };
129 
130 struct stob_perf {
131  struct m0_stob sp_stob;
135  uint64_t sp_magic;
136 
137  /* List of I/Os and latency logics */
138  struct m0_tl sp_ios;
142 };
143 
144 struct stob_perf_io {
150  uint64_t spi_magic;
151 };
152 
155 static const struct m0_stob_io_op stob_perf_io_ops;
156 
157 static void stob_perf_io_completed(struct stob_perf_io *pio);
158 
159 enum {
161  /* Default size of the tmpfs in MB. */
163 };
164 
165 #define STOB_PERF_DOM_CONFIG_PATH "/config"
166 #define STOB_PERF_DOM_LDOM_PATH "/backstore"
167 
168 M0_TL_DESCR_DEFINE(stob_perf_ios, "List of perfstob I/O",
169  static, struct stob_perf_io, spi_link, spi_magic,
171 M0_TL_DEFINE(stob_perf_ios, static, struct stob_perf_io);
172 
174 {
175 }
176 
178 {
179 }
180 
181 static struct stob_perf_domain *
183 {
184  struct stob_perf_domain *pdom =
187  return pdom;
188 }
189 
190 static struct stob_perf *stob_perf_container(struct m0_stob *stob)
191 {
192  struct stob_perf *pstob = container_of(stob, struct stob_perf, sp_stob);
194  return pstob;
195 }
196 
198 {
199  return pio->spi_pstob->sp_pdom->spd_cfg.spc_latency;
200 }
201 
202 static int stob_perf_domain_cfg_init_parse(const char *str_cfg_init,
203  void **cfg_init)
204 {
205  return 0;
206 }
207 
208 static void stob_perf_domain_cfg_init_free(void *cfg_init)
209 {
210 }
211 
212 static int stob_perf_domain_cfg_create_parse(const char *str_cfg_create,
213  void **cfg_create)
214 {
215  int rc = 0;
216 
217  M0_PRE(cfg_create != NULL);
218 
219  *cfg_create = NULL;
220  if (str_cfg_create != NULL) {
221  *cfg_create = m0_strdup(str_cfg_create);
222  rc = *cfg_create == NULL ? M0_ERR(-ENOMEM) : 0;
223  }
224  return M0_RC(rc);
225 }
226 
227 static void stob_perf_domain_cfg_create_free(void *cfg_create)
228 {
229  if (cfg_create != NULL)
230  m0_free(cfg_create);
231 }
232 
233 static char *stob_perf_domain_config(const char *location_data)
234 {
235  char *config_path;
236 
237  config_path = m0_alloc(strlen(location_data) +
238  strlen(STOB_PERF_DOM_CONFIG_PATH) + 1);
239  if (config_path != NULL) {
240  strcpy(config_path, location_data);
241  strcat(config_path, STOB_PERF_DOM_CONFIG_PATH);
242  }
243  return config_path;
244 }
245 
246 static char *stob_perf_domain_ldom_location(const char *location_data)
247 {
248  char *ldom_location;
249 
250 #define __LINUXSTOB "linuxstob:"
251  ldom_location = m0_alloc(strlen(__LINUXSTOB) + strlen(location_data) +
252  strlen(STOB_PERF_DOM_LDOM_PATH) + 1);
253  if (ldom_location != NULL) {
254  strcpy(ldom_location, __LINUXSTOB);
255  strcat(ldom_location, location_data);
256  strcat(ldom_location, STOB_PERF_DOM_LDOM_PATH);
257  }
258 #undef __LINUXSTOB
259  return ldom_location;
260 }
261 
263  const char *cfg_str)
264 {
265  /* XXX TODO Define config format and parse it properly. */
266 
267  cfg->spc_is_null = cfg_str != NULL &&
268  (strstr(cfg_str, "null=true") != NULL ||
269  strstr(cfg_str, "null=1") != NULL);
270  M0_LOG(M0_DEBUG, "spc_is_null=%d", !!cfg->spc_is_null);
271 
272  cfg->spc_tmpfs_size = cfg->spc_is_null ? 64 : 256; /* XXX */
275 
276  /* Don't allow latency longer than 2 seconds, it's converted to long. */
278 }
279 
281  const char *location_data)
282 {
283  struct stat st;
284  char *config_path;
285  char *cfg_str;
286  bool cfg_allocated = false;
287  FILE *f;
288  size_t len;
289  size_t read;
290  int rc;
291 
292  config_path = stob_perf_domain_config(location_data);
293  if (config_path == NULL)
294  return M0_ERR(-ENOMEM);
295 
296  rc = stat(config_path, &st);
297  rc = rc != 0 ? M0_ERR(-errno) : 0;
298  if (rc == 0) {
299  len = st.st_size + 1;
300  cfg_str = m0_alloc(len);
301  rc = cfg_str == NULL ? M0_ERR(-ENOMEM) : 0;
302  }
303  if (rc == 0) {
304  cfg_allocated = true;
305  f = fopen(config_path, "r");
306  rc = f == NULL ? M0_ERR(-errno) : 0;
307  }
308  if (rc == 0) {
309  read = fread(cfg_str, 1, len - 1, f);
310  rc = ferror(f) != 0 ? M0_ERR(-errno) : 0;
311  if (rc == 0) {
312  M0_ASSERT(read < len);
313  cfg_str[read] = '\0';
314  }
315  (void)fclose(f);
316  }
317  if (rc == 0)
318  stob_perf_domain_cfg_parse(&pdom->spd_cfg, cfg_str);
319 
320  if (cfg_allocated)
321  m0_free(cfg_str);
322  m0_free(config_path);
323 
324  return M0_RC(rc);
325 }
326 
327 static int stob_perf_domain_write_config(const char *cfg_str,
328  uint64_t dom_key,
329  const char *location_data)
330 {
331  char *config_path;
332  size_t written;
333  FILE *f;
334  int rc;
335  int rc2;
336 
337  config_path = stob_perf_domain_config(location_data);
338  if (config_path == NULL)
339  return M0_ERR(-ENOMEM);
340 
341  f = fopen(config_path, "w");
342  rc = f == NULL ? M0_ERR(-errno) : 0;
343  if (rc == 0 && cfg_str != NULL) {
344  written = fwrite(cfg_str, 1, strlen(cfg_str), f);
345  if (written != strlen(cfg_str))
346  rc = ferror(f) != 0 ? M0_ERR(-errno) : M0_ERR(-EINVAL);
347  }
348  if (f != NULL) {
349  rc2 = fclose(f);
350  rc2 = rc2 == EOF ? M0_ERR(-errno) : 0;
351  rc = rc ?: rc2;
352  }
353  m0_free(config_path);
354 
355  return M0_RC(rc);
356 }
357 
359  const char *location_data,
360  void *cfg_init,
361  struct m0_stob_domain **out)
362 {
363  struct stob_perf_domain *pdom;
364  struct m0_fid dom_id;
365  uint64_t dom_key;
366  uint8_t type_id;
367  char *ldom_location;
368  int rc;
369 
370  M0_PRE(out != NULL);
371 
372  M0_ALLOC_PTR(pdom);
373  ldom_location = stob_perf_domain_ldom_location(location_data);
374 
375  if (pdom == NULL || ldom_location == NULL) {
376  m0_free(pdom);
377  m0_free(ldom_location);
378  return M0_ERR(-ENOMEM);
379  }
380 
381  rc = stob_perf_domain_read_config(pdom, location_data);
382  if (rc == 0)
383  rc = m0_stob_domain_init(ldom_location, NULL, &pdom->spd_ldom);
384  M0_ASSERT(ergo(rc == 0, pdom->spd_ldom != NULL));
385 
386  if (rc == 0) {
387  dom_key = m0_stob_domain__dom_key(
390  type_id = m0_stob_type_id_get(type);
391  m0_stob_domain__dom_id_make(&dom_id, type_id, 0, dom_key);
392  m0_stob_domain__id_set(&pdom->spd_dom, &dom_id);
393 
396  *out = &pdom->spd_dom;
397  }
398  m0_free(ldom_location);
399 
400  return M0_RC(rc);
401 }
402 
404 {
406 
408  m0_free(pdom);
409 }
410 
411 static int stob_perf_domain_dir_clean(const char *location_data)
412 {
413  int rc;
414 
415  (void)umount(location_data);
416  rc = rmdir(location_data);
417  rc = rc != 0 ? M0_ERR(-errno) : 0;
418 
419  return M0_RC(rc);
420 }
421 
422 static int stob_perf_domain_tmpfs_opts(char *opts,
423  size_t opts_len,
424  struct stob_perf_domain_cfg *cfg)
425 {
426  size_t size;
427  int i = 0;
428  int rc;
429 
430  static char sfx[] = { 'M', 'G', 'T' };
431 
433  cfg->spc_tmpfs_size;
434 
435  if (size >= 1024 * 1024 * 1024)
436  return M0_ERR(-EOVERFLOW);
437 
438  for (i = 0; size >= 1024; ++i)
439  size /= 1024;
440  rc = snprintf(opts, opts_len, "size=%zu%c", size, sfx[i]);
441  if (rc >= opts_len)
442  return M0_ERR(-ERANGE);
443 
444  return 0;
445 }
446 
448  const char *location_data,
449  uint64_t dom_key,
450  void *cfg_create)
451 {
452  struct stob_perf_domain_cfg cfg = {};
453  struct m0_stob_domain *ldom = NULL;
454  const char *cfg_str = cfg_create;
455  char tmpfs_opts[16];
456  char *ldom_location;
457  bool dir_created = false;
458  int rc;
459 
460  stob_perf_domain_cfg_parse(&cfg, cfg_str);
461  rc = stob_perf_domain_tmpfs_opts(tmpfs_opts, sizeof tmpfs_opts, &cfg);
462  if (rc != 0)
463  return rc;
464 
465  ldom_location = stob_perf_domain_ldom_location(location_data);
466  if (ldom_location == NULL)
467  return M0_ERR(-ENOMEM);
468 
469  rc = mkdir(location_data, 0700);
470  rc = rc != 0 ? M0_ERR(-errno) : 0;
471 #ifdef STOB_PERF_DOMAIN_CREATE_FORCE
472  /* XXX This section is disabled to satisfy stob/ut/domain.c checks. */
473  if (rc == -EEXIST) {
474  rc = stob_perf_domain_dir_clean(location_data);
475  if (rc == 0) {
476  rc = mkdir(location_data, 0700);
477  rc = rc != 0 ? M0_ERR(-errno) : 0;
478  }
479  }
480 #endif
481  if (rc == 0) {
482  dir_created = true;
483  rc = mount("none", location_data, "tmpfs", MS_NODEV | MS_NOEXEC,
484  tmpfs_opts);
485  rc = rc != 0 ? M0_ERR(-errno) : 0;
486  }
487  if (rc == 0)
488  rc = stob_perf_domain_write_config(cfg_str, dom_key,
489  location_data);
490  if (rc == 0)
491  rc = m0_stob_domain_create(ldom_location, NULL, dom_key,
492  NULL, &ldom);
493  M0_ASSERT(ergo(rc == 0, ldom != NULL));
494  if (rc == 0)
495  m0_stob_domain_fini(ldom);
496 
497  m0_free(ldom_location);
498 
499  if (rc != 0 && dir_created)
500  (void)stob_perf_domain_dir_clean(location_data);
501 
502  return M0_RC(rc);
503 }
504 
506  const char *location_data)
507 {
508  char *ldom_location = stob_perf_domain_ldom_location(location_data);
509  int rc;
510 
511  if (ldom_location == NULL)
512  return M0_ERR(-ENOMEM);
513 
514  /* XXX TODO dump stats somewhere */
515 
516  rc = m0_stob_domain_destroy_location(ldom_location);
517  if (rc != 0)
518  M0_LOG(M0_ERROR, "Couldn't destroy linux domain: rc=%d", rc);
519  m0_free(ldom_location);
520  /*
521  * Destroy the domain regardless of the previous errors. Destroy()
522  * has to work even for partially created domains.
523  */
524  rc = stob_perf_domain_dir_clean(location_data);
525 
526  return M0_RC(rc);
527 }
528 
529 static struct m0_stob *stob_perf_alloc(struct m0_stob_domain *dom,
530  const struct m0_fid *stob_fid)
531 {
532  struct stob_perf *pstob;
533 
534  M0_ALLOC_PTR(pstob);
535  if (pstob != NULL)
536  pstob->sp_magic = M0_STOB_PERF_MAGIC;
537  return pstob == NULL ? NULL : &pstob->sp_stob;
538 }
539 
540 static void stob_perf_free(struct m0_stob_domain *dom,
541  struct m0_stob *stob)
542 {
543  struct stob_perf *pstob = stob_perf_container(stob);
544 
545  m0_free(pstob);
546 }
547 
548 static int stob_perf_cfg_parse(const char *str_cfg_create,
549  void **cfg_create)
550 {
551  return 0;
552 }
553 
554 static void stob_perf_cfg_free(void *cfg_create)
555 {
556 }
557 
558 static void stob_perf_linux_fid_set(struct m0_fid *lstob_fid,
559  const struct m0_fid *stob_fid,
560  struct stob_perf_domain *pdom)
561 {
562  *lstob_fid = *stob_fid;
565 }
566 
568  const struct m0_fid *stob_fid,
569  struct m0_dtx *dtx,
570  bool create,
571  struct m0_stob **out)
572 {
573  struct m0_stob *lstob;
574  struct m0_fid lstob_fid;
575  const char *create_cfg;
576  int rc;
577 
578  stob_perf_linux_fid_set(&lstob_fid, stob_fid, pdom);
579  rc = m0_stob_find_by_key(pdom->spd_ldom, &lstob_fid, &lstob);
580  if (rc != 0)
581  return M0_RC(rc);
582 
583  M0_ASSERT(lstob != NULL);
584  if (m0_stob_state_get(lstob) == CSS_UNKNOWN)
585  rc = m0_stob_locate(lstob);
586  if (rc == 0 && create && m0_stob_state_get(lstob) != CSS_NOENT)
587  rc = M0_ERR(-EEXIST);
588  if (rc == 0 && !create && m0_stob_state_get(lstob) != CSS_EXISTS)
589  rc = M0_ERR(-ENOENT);
590  if (rc == 0 && create) {
591  create_cfg = pdom->spd_cfg.spc_is_null ? "/dev/null" : NULL;
592  rc = m0_stob_create(lstob, dtx, create_cfg);
593  }
594  if (rc != 0)
595  m0_stob_put(lstob);
596  if (rc == 0)
597  *out = lstob;
598  return M0_RC(rc);
599 }
600 
601 static void stob_perf_timer_start(struct stob_perf *pstob,
602  struct stob_perf_io *pio)
603 {
604  m0_time_t latency;
605 
606  latency = pstob->sp_pdom->spd_cfg.spc_latency_cb(pio);
607  m0_timer_start(&pstob->sp_timer, m0_time_from_now(0, latency));
608 }
609 
610 static void stob_perf_ast_cb(struct m0_sm_group *grp, struct m0_sm_ast *ast)
611 {
612  struct stob_perf *pstob =
613  container_of(ast, struct stob_perf, sp_ast);
614  struct stob_perf_io *pio;
615  struct stob_perf_io *pio2;
616 
617  M0_PRE(pstob == ast->sa_datum);
619 
620  m0_timer_stop(&pstob->sp_timer);
621 
622  m0_mutex_lock(&pstob->sp_lock);
623  pio = stob_perf_ios_tlist_pop(&pstob->sp_ios);
624  M0_ASSERT(pio != NULL);
625  if (!stob_perf_ios_tlist_is_empty(&pstob->sp_ios)) {
626  pio2 = stob_perf_ios_tlist_head(&pstob->sp_ios);
627  M0_ASSERT(pio2 != NULL);
628  stob_perf_timer_start(pstob, pio2);
629  }
630  m0_mutex_unlock(&pstob->sp_lock);
632 }
633 
634 static unsigned long stob_perf_timer_cb(unsigned long data)
635 {
636  struct stob_perf *pstob = (struct stob_perf *)data;
637  struct m0_locality *loc;
638 
640 
641  loc = m0_locality_get(data);
642  M0_ASSERT(loc != NULL);
643  pstob->sp_ast.sa_cb = &stob_perf_ast_cb;
644  pstob->sp_ast.sa_datum = pstob;
645  m0_sm_ast_post(loc->lo_grp, &pstob->sp_ast);
646 
647  return 0; /* XXX what to return here? */
648 }
649 
650 static int stob_perf_init(struct m0_stob *stob,
651  struct m0_stob_domain *dom,
652  const struct m0_fid *stob_fid)
653 {
655  struct stob_perf *pstob = stob_perf_container(stob);
656  struct m0_stob *lstob;
657  int rc;
658 
659  M0_ENTRY();
660 
662  &stob_perf_timer_cb, (unsigned long)pstob);
663  if (rc == 0) {
664  rc = stob_perf_linux_init_create(pdom, stob_fid, NULL,
665  false, &lstob);
666  if (rc != 0)
667  m0_timer_fini(&pstob->sp_timer);
668  }
669  if (rc == 0) {
671  pstob->sp_pdom = pdom;
672  pstob->sp_backstore = lstob;
673  stob_perf_ios_tlist_init(&pstob->sp_ios);
674  m0_mutex_init(&pstob->sp_lock);
675  M0_SET0(&pstob->sp_ast);
676  /* XXX TODO init stats */
677  }
678  return M0_RC(rc);
679 }
680 
681 static void stob_perf_fini(struct m0_stob *stob)
682 {
683  struct stob_perf *pstob = stob_perf_container(stob);
684 
685  M0_ENTRY();
686 
687  /* XXX TODO dump stats? */
688 
689  m0_timer_fini(&pstob->sp_timer);
690  m0_mutex_fini(&pstob->sp_lock);
691  stob_perf_ios_tlist_fini(&pstob->sp_ios);
692 
693  /* Assume backstore is NULL when the stob is being destroyed. */
694  if (pstob->sp_backstore != NULL) {
695  m0_stob_put(pstob->sp_backstore);
696  pstob->sp_backstore = NULL;
697  }
698  M0_LEAVE();
699 }
700 
702  struct m0_be_tx_credit *accum)
703 {
705 
706  m0_stob_create_credit(pdom->spd_ldom, accum);
707 }
708 
709 static int stob_perf_create(struct m0_stob *stob,
710  struct m0_stob_domain *dom,
711  struct m0_dtx *dtx,
712  const struct m0_fid *stob_fid,
713  void *cfg)
714 {
716  struct m0_stob *lstob;
717  int rc;
718 
719  rc = stob_perf_linux_init_create(pdom, stob_fid, dtx, true, &lstob);
720  if (rc == 0) {
721  m0_stob_put(lstob);
722  rc = stob_perf_init(stob, dom, stob_fid);
723  }
724  return M0_RC(rc);
725 }
726 
728  struct m0_be_tx_credit *accum)
729 {
730  struct stob_perf *pstob = stob_perf_container(stob);
731 
732  m0_stob_destroy_credit(pstob->sp_backstore, accum);
733 }
734 
735 static int stob_perf_destroy(struct m0_stob *stob, struct m0_dtx *dtx)
736 {
737  struct stob_perf *pstob = stob_perf_container(stob);
738  int rc;
739 
740  rc = m0_stob_destroy(pstob->sp_backstore, dtx);
741  if (rc == 0)
742  pstob->sp_backstore = NULL;
743 
744  return M0_RC(rc);
745 }
746 
748  struct m0_indexvec *want,
749  struct m0_indexvec *got,
750  struct m0_be_tx_credit *accum)
751 {
752  struct stob_perf *pstob = stob_perf_container(stob);
753 
754  got->iv_index[0] = 0;
755  got->iv_vec.v_count[0] = M0_BINDEX_MAX + 1;
756  if (pstob->sp_pdom->spd_cfg.spc_is_null)
757  return 0;
758  else
759  return m0_stob_punch_credit(pstob->sp_backstore, want, got,
760  accum);
761 }
762 
763 static int stob_perf_punch(struct m0_stob *stob,
764  struct m0_indexvec *range,
765  struct m0_dtx *dtx)
766 {
767  struct stob_perf *pstob = stob_perf_container(stob);
768 
769  if (pstob->sp_pdom->spd_cfg.spc_is_null)
770  return 0;
771  else
772  return m0_stob_punch(pstob->sp_backstore, range, dtx);
773 }
774 
775 static void stob_perf_write_credit(const struct m0_stob_domain *dom,
776  const struct m0_stob_io *io,
777  struct m0_be_tx_credit *accum)
778 {
779  struct stob_perf_domain *pdom =
781 
782  m0_stob_io_credit(io, pdom->spd_ldom, accum);
783 }
784 
785 static uint32_t stob_perf_block_shift(struct m0_stob *stob)
786 {
787  struct stob_perf *pstob = stob_perf_container(stob);
788 
789  return m0_stob_block_shift(pstob->sp_backstore);
790 }
791 
792 static int stob_perf_fd(struct m0_stob *stob)
793 {
794  struct stob_perf *pstob = stob_perf_container(stob);
795 
796  return m0_stob_fd(pstob->sp_backstore);
797 }
798 
799 static void stob_perf_consume_io(struct stob_perf_io *pio)
800 {
801  struct stob_perf *pstob = pio->spi_pstob;
802 
803  m0_mutex_lock(&pstob->sp_lock);
804  if (stob_perf_ios_tlist_is_empty(&pstob->sp_ios))
805  stob_perf_timer_start(pstob, pio);
806  stob_perf_ios_tlist_add_tail(&pstob->sp_ios, pio);
807  m0_mutex_unlock(&pstob->sp_lock);
808 }
809 
810 static void stob_perf_io_completed(struct stob_perf_io *pio)
811 {
812  struct m0_stob_io *io = pio->spi_io;
813  struct m0_stob_io *lio = &pio->spi_lio;
814 
815  io->si_rc = lio->si_rc;
816  io->si_count = lio->si_count;
817  io->si_state = SIS_IDLE;
819 }
820 
822 {
823  struct stob_perf_io *pio =
825 
827 
828  m0_clink_del(&pio->spi_clink);
830 
831  return true;
832 }
833 
834 static int stob_perf_io_init(struct m0_stob *stob,
835  struct m0_stob_io *io)
836 {
837  struct stob_perf *pstob = stob_perf_container(stob);
838  struct stob_perf_io *pio;
839 
840  M0_ALLOC_PTR(pio);
841  if (pio == NULL)
842  return M0_ERR(-ENOMEM);
843 
845  m0_stob_io_init(&pio->spi_lio);
846  stob_perf_ios_tlink_init(pio);
848  io->si_stob_private = pio;
849  pio->spi_io = io;
850  pio->spi_pstob = pstob;
851 
852  return M0_RC(0);
853 }
854 
855 static int stob_perf_io_launch(struct m0_stob_io *io)
856 {
857  struct stob_perf_io *pio = io->si_stob_private;
858  struct stob_perf *pstob = pio->spi_pstob;
859  struct m0_stob_io *lio = &pio->spi_lio;
860  int rc;
861 
862  lio->si_flags = io->si_flags;
863  lio->si_user = io->si_user;
864  lio->si_stob = io->si_stob;
865  lio->si_opcode = io->si_opcode;
866 
867  m0_clink_add_lock(&lio->si_wait, &pio->spi_clink);
868 
870  io->si_scope);
871  return M0_RC(rc);
872 }
873 
874 static void stob_perf_io_fini(struct m0_stob_io *io)
875 {
876  struct stob_perf_io *pio = io->si_stob_private;
877 
878  stob_perf_ios_tlink_fini(pio);
879  m0_stob_io_fini(&pio->spi_lio);
880  m0_clink_fini(&pio->spi_clink);
881  m0_free(pio);
882 }
883 
886  .sto_deregister = &stob_perf_type_deregister,
887  .sto_domain_cfg_init_parse = &stob_perf_domain_cfg_init_parse,
888  .sto_domain_cfg_init_free = &stob_perf_domain_cfg_init_free,
889  .sto_domain_cfg_create_parse = &stob_perf_domain_cfg_create_parse,
890  .sto_domain_cfg_create_free = &stob_perf_domain_cfg_create_free,
891  .sto_domain_init = &stob_perf_domain_init,
892  .sto_domain_create = &stob_perf_domain_create,
893  .sto_domain_destroy = &stob_perf_domain_destroy,
894 };
895 
898  .sdo_stob_alloc = &stob_perf_alloc,
899  .sdo_stob_free = &stob_perf_free,
900  .sdo_stob_cfg_parse = &stob_perf_cfg_parse,
901  .sdo_stob_cfg_free = &stob_perf_cfg_free,
902  .sdo_stob_init = &stob_perf_init,
903  .sdo_stob_create_credit = &stob_perf_create_credit,
904  .sdo_stob_create = &stob_perf_create,
905  .sdo_stob_write_credit = &stob_perf_write_credit,
906 };
907 
908 static struct m0_stob_ops stob_perf_ops = {
910  .sop_destroy_credit = &stob_perf_destroy_credit,
911  .sop_destroy = &stob_perf_destroy,
912  .sop_punch_credit = &stob_perf_punch_credit,
913  .sop_punch = &stob_perf_punch,
914  .sop_io_init = &stob_perf_io_init,
915  .sop_block_shift = &stob_perf_block_shift,
916  .sop_fd = &stob_perf_fd,
917 };
918 
919 static const struct m0_stob_io_op stob_perf_io_ops = {
921  .sio_fini = stob_perf_io_fini
922 };
923 
926  .st_fidt = {
927  .ft_id = STOB_TYPE_PERF,
928  .ft_name = "perfstob",
929  },
930 };
931 
934 #undef M0_TRACE_SUBSYSTEM
935 
936 /*
937  * Local variables:
938  * c-indentation-style: "K&R"
939  * c-basic-offset: 8
940  * tab-width: 8
941  * fill-column: 80
942  * scroll-step: 1
943  * End:
944  */
945 /*
946  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
947  */
struct m0_clink spi_clink
Definition: perf.c:148
static int stob_perf_domain_tmpfs_opts(char *opts, size_t opts_len, struct stob_perf_domain_cfg *cfg)
Definition: perf.c:422
const struct m0_stob_type m0_stob_perf_type
Definition: perf.c:924
static int stob_perf_cfg_parse(const char *str_cfg_create, void **cfg_create)
Definition: perf.c:548
#define M0_PRE(cond)
Definition: dtm.h:554
enum m0_stob_io_flags si_flags
Definition: io.h:290
uint64_t spd_magic
Definition: perf.c:121
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
M0_INTERNAL uint64_t m0_stob_domain__dom_key(const struct m0_fid *dom_id)
Definition: domain.c:322
#define m0_strdup(s)
Definition: string.h:43
void(* sto_register)(struct m0_stob_type *type)
Definition: type.h:73
M0_INTERNAL void m0_chan_broadcast_lock(struct m0_chan *chan)
Definition: chan.c:178
M0_INTERNAL void m0_stob_io_fini(struct m0_stob_io *io)
Definition: io.c:122
M0_INTERNAL void m0_stob_domain__dom_id_make(struct m0_fid *dom_id, uint8_t type_id, uint64_t dom_container, uint64_t dom_key)
Definition: domain.c:327
M0_INTERNAL struct m0_locality * m0_locality_get(uint64_t value)
Definition: locality.c:156
M0_INTERNAL int struct dentry struct kstat * stat
Definition: dir.c:1433
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_clink_init(struct m0_clink *link, m0_chan_cb_t cb)
Definition: chan.c:201
M0_INTERNAL void m0_clink_del(struct m0_clink *link)
Definition: chan.c:267
static void stob_perf_linux_fid_set(struct m0_fid *lstob_fid, const struct m0_fid *stob_fid, struct stob_perf_domain *pdom)
Definition: perf.c:558
static const struct m0_stob_io_op stob_perf_io_ops
Definition: perf.c:155
M0_INTERNAL int m0_stob_locate(struct m0_stob *stob)
Definition: stob.c:128
struct stob_perf * spi_pstob
Definition: perf.c:147
const struct m0_stob_ops * so_ops
Definition: stob.h:164
#define ergo(a, b)
Definition: misc.h:293
M0_INTERNAL void m0_stob_io_credit(const struct m0_stob_io *io, const struct m0_stob_domain *dom, struct m0_be_tx_credit *accum)
Definition: io.c:130
void(* sa_cb)(struct m0_sm_group *grp, struct m0_sm_ast *)
Definition: sm.h:506
static int stob_perf_domain_destroy(struct m0_stob_type *type, const char *location_data)
Definition: perf.c:505
static int stob_perf_domain_read_config(struct stob_perf_domain *pdom, const char *location_data)
Definition: perf.c:280
static FILE * f
Definition: adieu.c:79
struct stob_perf_domain * sp_pdom
Definition: perf.c:134
static struct m0_sm_group * grp
Definition: bytecount.c:38
static int stob_perf_io_init(struct m0_stob *stob, struct m0_stob_io *io)
Definition: perf.c:834
uint64_t m0_time_t
Definition: time.h:37
#define M0_LOG(level,...)
Definition: trace.h:167
M0_INTERNAL int m0_stob_find_by_key(struct m0_stob_domain *dom, const struct m0_fid *stob_fid, struct m0_stob **out)
Definition: stob.c:65
M0_LEAVE()
static void stob_perf_ast_cb(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: perf.c:610
M0_INTERNAL const struct m0_fid * m0_stob_domain_id_get(const struct m0_stob_domain *dom)
Definition: domain.c:300
M0_INTERNAL void m0_sm_ast_post(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: sm.c:135
struct m0_sm_ast sp_ast
Definition: perf.c:141
static bool stob_perf_io_lio_completed(struct m0_clink *clink)
Definition: perf.c:821
static void create(void)
Definition: service_ut.c:546
static void stob_perf_timer_start(struct stob_perf *pstob, struct stob_perf_io *pio)
Definition: perf.c:601
static void stob_perf_domain_cfg_create_free(void *cfg_create)
Definition: perf.c:227
static void stob_perf_fini(struct m0_stob *stob)
Definition: perf.c:681
struct m0_tl sp_ios
Definition: perf.c:138
struct m0_bufvec data
Definition: di.c:40
const struct m0_stob_io_op * si_op
Definition: io.h:328
M0_INTERNAL uint8_t m0_stob_type_id_get(const struct m0_stob_type *type)
Definition: type.c:164
uint64_t sp_magic
Definition: perf.c:135
struct m0_tlink spi_link
Definition: perf.c:149
struct m0_chan si_wait
Definition: io.h:318
static void stob_perf_consume_io(struct stob_perf_io *pio)
Definition: perf.c:799
M0_INTERNAL int m0_timer_init(struct m0_timer *timer, enum m0_timer_type type, struct m0_timer_locality *loc, m0_timer_callback_t callback, unsigned long data)
Definition: timer.c:39
Definition: sm.h:504
static void stob_perf_domain_cfg_init_free(void *cfg_init)
Definition: perf.c:208
#define container_of(ptr, type, member)
Definition: misc.h:33
#define M0_SET0(obj)
Definition: misc.h:64
void(* sdo_fini)(struct m0_stob_domain *dom)
Definition: domain.h:111
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
Definition: timer.h:39
static int stob_perf_domain_cfg_create_parse(const char *str_cfg_create, void **cfg_create)
Definition: perf.c:212
static int stob_perf_destroy(struct m0_stob *stob, struct m0_dtx *dtx)
Definition: perf.c:735
int(* sio_launch)(struct m0_stob_io *io)
Definition: io.h:439
static int stob_perf_domain_dir_clean(const char *location_data)
Definition: perf.c:411
static int stob_perf_punch(struct m0_stob *stob, struct m0_indexvec *range, struct m0_dtx *dtx)
Definition: perf.c:763
static void stob_perf_free(struct m0_stob_domain *dom, struct m0_stob *stob)
Definition: perf.c:540
struct m0_vec iv_vec
Definition: vec.h:139
return M0_RC(rc)
M0_INTERNAL uint32_t m0_stob_block_shift(struct m0_stob *stob)
Definition: stob.c:270
M0_INTERNAL void m0_timer_fini(struct m0_timer *timer)
Definition: timer.c:65
struct m0_bufvec si_user
Definition: io.h:300
#define M0_ENTRY(...)
Definition: trace.h:170
static struct m0_sm_ast ast[NR]
Definition: locality.c:44
static int stob_perf_init(struct m0_stob *stob, struct m0_stob_domain *dom, const struct m0_fid *stob_fid)
Definition: perf.c:650
m0_bindex_t * iv_index
Definition: vec.h:141
static struct m0_stob * stob_perf_alloc(struct m0_stob_domain *dom, const struct m0_fid *stob_fid)
Definition: perf.c:529
int i
Definition: dir.c:1033
M0_INTERNAL bool m0_stob_domain__dom_key_is_valid(uint64_t dom_key)
Definition: domain.c:344
M0_INTERNAL int m0_stob_domain_create(const char *location, const char *str_cfg_init, uint64_t dom_key, const char *str_cfg_create, struct m0_stob_domain **out)
Definition: domain.c:217
struct m0_dtx * si_tx
Definition: io.h:351
static void stob_perf_type_deregister(struct m0_stob_type *type)
Definition: perf.c:177
return M0_ERR(-EOPNOTSUPP)
void * sa_datum
Definition: sm.h:508
static int stob_perf_punch_credit(struct m0_stob *stob, struct m0_indexvec *want, struct m0_indexvec *got, struct m0_be_tx_credit *accum)
Definition: perf.c:747
static char * stob_perf_domain_config(const char *location_data)
Definition: perf.c:233
M0_INTERNAL int m0_stob_io_prepare_and_launch(struct m0_stob_io *io, struct m0_stob *obj, struct m0_dtx *tx, struct m0_io_scope *scope)
Definition: io.c:219
Definition: stob.h:163
M0_INTERNAL void m0_timer_stop(struct m0_timer *timer)
Definition: timer.c:86
struct m0_indexvec si_stob
Definition: io.h:311
int32_t si_rc
Definition: io.h:334
#define STOB_PERF_DOM_CONFIG_PATH
Definition: perf.c:165
size_t spc_tmpfs_size
Definition: perf.c:110
static struct m0_stob * stob
Definition: storage.c:39
static struct m0_stob_ops stob_perf_ops
Definition: perf.c:154
#define M0_ASSERT(cond)
M0_INTERNAL void m0_timer_start(struct m0_timer *timer, m0_time_t expire)
Definition: timer.c:75
M0_INTERNAL void m0_stob_destroy_credit(struct m0_stob *stob, struct m0_be_tx_credit *accum)
Definition: stob.c:187
static struct stob_perf_domain * stob_perf_domain_container(struct m0_stob_domain *dom)
Definition: perf.c:182
static void stob_perf_write_credit(const struct m0_stob_domain *dom, const struct m0_stob_io *io, struct m0_be_tx_credit *accum)
Definition: perf.c:775
Definition: tlist.h:251
static void stob_perf_domain_fini(struct m0_stob_domain *dom)
Definition: perf.c:403
stob_perf_latency_cb_t spc_latency_cb
Definition: perf.c:113
static struct m0_stob_domain * dom
Definition: storage.c:38
Definition: io.h:244
static void stob_perf_io_completed(struct stob_perf_io *pio)
Definition: perf.c:810
void * m0_alloc(size_t size)
Definition: memory.c:126
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
#define M0_POST(cond)
struct m0_stob sp_stob
Definition: perf.c:131
struct m0_sm_group * lo_grp
Definition: locality.h:67
static int stob_perf_io_launch(struct m0_stob_io *io)
Definition: perf.c:855
enum m0_stob_io_state si_state
Definition: io.h:345
Definition: io.h:285
m0_bcount_t * v_count
Definition: vec.h:53
static struct m0_clink clink[RDWR_REQUEST_MAX]
struct m0_stob_domain spd_dom
Definition: perf.c:117
m0_time_t spc_latency
Definition: perf.c:112
m0_time_t(* stob_perf_latency_cb_t)(struct stob_perf_io *)
Definition: perf.c:107
static struct m0_stob_io io
Definition: ad.c:59
m0_bcount_t si_count
Definition: io.h:340
struct m0_stob_io spi_lio
Definition: perf.c:146
M0_TL_DESCR_DEFINE(stob_perf_ios, "List of perfstob I/O", static, struct stob_perf_io, spi_link, spi_magic, M0_STOB_PERF_IO_MAGIC, M0_STOB_PERF_IO_HEAD_MAGIC)
static void stob_perf_cfg_free(void *cfg_create)
Definition: perf.c:554
M0_INTERNAL void m0_stob_domain_fini(struct m0_stob_domain *dom)
Definition: domain.c:204
M0_INTERNAL int m0_stob_create(struct m0_stob *stob, struct m0_dtx *dtx, const char *str_cfg)
Definition: stob.c:154
void m0_clink_add_lock(struct m0_chan *chan, struct m0_clink *link)
Definition: chan.c:255
static uint32_t stob_perf_block_shift(struct m0_stob *stob)
Definition: perf.c:785
M0_INTERNAL int m0_stob_punch_credit(struct m0_stob *stob, struct m0_indexvec *want, struct m0_indexvec *got, struct m0_be_tx_credit *accum)
Definition: stob.c:223
M0_INTERNAL int m0_stob_domain_destroy_location(const char *location)
Definition: domain.c:242
static struct stob_perf * stob_perf_container(struct m0_stob *stob)
Definition: perf.c:190
static int stob_perf_domain_init(struct m0_stob_type *type, const char *location_data, void *cfg_init, struct m0_stob_domain **out)
Definition: perf.c:358
static void stob_perf_domain_cfg_parse(struct stob_perf_domain_cfg *cfg, const char *cfg_str)
Definition: perf.c:262
M0_INTERNAL int m0_stob_destroy(struct m0_stob *stob, struct m0_dtx *dtx)
Definition: stob.c:200
static int stob_perf_domain_cfg_init_parse(const char *str_cfg_init, void **cfg_init)
Definition: perf.c:202
static unsigned long stob_perf_timer_cb(unsigned long data)
Definition: perf.c:634
M0_INTERNAL enum m0_stob_state m0_stob_state_get(struct m0_stob *stob)
Definition: stob.c:265
void(* sop_fini)(struct m0_stob *stob)
Definition: stob.h:187
struct m0_mutex sp_lock
Definition: perf.c:139
Definition: stob.h:91
void * si_stob_private
Definition: io.h:367
static struct m0_stob_type_ops stob_perf_type_ops
Definition: perf.c:884
M0_INTERNAL int m0_stob_domain_init(const char *location, const char *str_cfg_init, struct m0_stob_domain **out)
Definition: domain.c:195
M0_INTERNAL void m0_fid_tchange(struct m0_fid *fid, uint8_t tid)
Definition: fid.c:139
static int stob_perf_linux_init_create(struct stob_perf_domain *pdom, const struct m0_fid *stob_fid, struct m0_dtx *dtx, bool create, struct m0_stob **out)
Definition: perf.c:567
Definition: fid.h:38
static void stob_perf_io_fini(struct m0_stob_io *io)
Definition: perf.c:874
M0_INTERNAL void m0_stob_domain__id_set(struct m0_stob_domain *dom, struct m0_fid *dom_id)
Definition: domain.c:311
struct m0_timer sp_timer
Definition: perf.c:140
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL int m0_stob_fd(struct m0_stob *stob)
Definition: stob.c:360
#define __LINUXSTOB
m0_time_t m0_time_from_now(uint64_t secs, long ns)
Definition: time.c:96
static int stob_perf_domain_write_config(const char *cfg_str, uint64_t dom_key, const char *location_data)
Definition: perf.c:327
int unused
Definition: perf.c:127
m0_bcount_t size
Definition: di.c:39
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
M0_INTERNAL void m0_clink_fini(struct m0_clink *link)
Definition: chan.c:208
static int stob_perf_create(struct m0_stob *stob, struct m0_stob_domain *dom, struct m0_dtx *dtx, const struct m0_fid *stob_fid, void *cfg)
Definition: perf.c:709
static m0_time_t stob_perf_latency_const(struct stob_perf_io *pio)
Definition: perf.c:197
M0_INTERNAL void m0_stob_io_init(struct m0_stob_io *io)
Definition: io.c:111
const struct m0_stob_domain_ops * sd_ops
Definition: domain.h:94
static char * stob_perf_domain_ldom_location(const char *location_data)
Definition: perf.c:246
struct stob_perf_domain_cfg spd_cfg
Definition: perf.c:120
struct stob_perf_stats sp_stats
Definition: perf.c:133
#define out(...)
Definition: gen.c:41
M0_INTERNAL int m0_stob_punch(struct m0_stob *stob, struct m0_indexvec *range, struct m0_dtx *dtx)
Definition: stob.c:232
M0_INTERNAL void m0_stob_create_credit(struct m0_stob_domain *dom, struct m0_be_tx_credit *accum)
Definition: stob.c:148
struct m0_stob_domain * spd_ldom
Definition: perf.c:119
int type
Definition: dir.c:1031
struct m0_stob_io * spi_io
Definition: perf.c:145
const struct m0_stob_type_ops * st_ops
Definition: type.h:60
static void stob_perf_type_register(struct m0_stob_type *type)
Definition: perf.c:173
M0_TL_DEFINE(stob_perf_ios, static, struct stob_perf_io)
static int stob_perf_fd(struct m0_stob *stob)
Definition: perf.c:792
static int stob_perf_domain_create(struct m0_stob_type *type, const char *location_data, uint64_t dom_key, void *cfg_create)
Definition: perf.c:447
static struct m0_stob_domain_ops stob_perf_domain_ops
Definition: perf.c:153
void m0_free(void *data)
Definition: memory.c:146
Definition: mutex.h:47
struct m0_io_scope * si_scope
Definition: io.h:355
static void stob_perf_create_credit(struct m0_stob_domain *dom, struct m0_be_tx_credit *accum)
Definition: perf.c:701
M0_INTERNAL uint8_t m0_stob_domain__type_id(const struct m0_fid *dom_id)
Definition: domain.c:317
int32_t rc
Definition: trigger_fop.h:47
uint64_t spi_magic
Definition: perf.c:150
M0_INTERNAL void m0_stob_put(struct m0_stob *stob)
Definition: stob.c:291
struct m0_stob * sp_backstore
Definition: perf.c:132
static void stob_perf_destroy_credit(struct m0_stob *stob, struct m0_be_tx_credit *accum)
Definition: perf.c:727
#define STOB_PERF_DOM_LDOM_PATH
Definition: perf.c:166
enum m0_stob_io_opcode si_opcode
Definition: io.h:286