1 /*
2 * Copyright (c) 2015-2016, Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2015, Intel Corp., Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 */
34
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38
39 #include <rdma/fi_errno.h>
40
41 #include "ofi.h"
42
43
44 static const char * const log_subsys[] = {
45 [FI_LOG_CORE] = "core",
46 [FI_LOG_FABRIC] = "fabric",
47 [FI_LOG_DOMAIN] = "domain",
48 [FI_LOG_EP_CTRL] = "ep_ctrl",
49 [FI_LOG_EP_DATA] = "ep_data",
50 [FI_LOG_AV] = "av",
51 [FI_LOG_CQ] = "cq",
52 [FI_LOG_EQ] = "eq",
53 [FI_LOG_MR] = "mr",
54 [FI_LOG_CNTR] = "cntr",
55 [FI_LOG_SUBSYS_MAX] = NULL
56 };
57
58 static const char * const log_levels[] = {
59 [FI_LOG_WARN] = "warn",
60 [FI_LOG_TRACE] = "trace",
61 [FI_LOG_INFO] = "info",
62 [FI_LOG_DEBUG] = "debug",
63 [FI_LOG_MAX] = NULL
64 };
65
66 enum {
67 FI_LOG_SUBSYS_OFFSET = FI_LOG_MAX,
68 FI_LOG_PROV_OFFSET = FI_LOG_SUBSYS_OFFSET + FI_LOG_SUBSYS_MAX,
69 FI_LOG_LEVEL_MASK = ((1 << FI_LOG_MAX) - 1),
70 FI_LOG_SUBSYS_MASK = (((1 << FI_LOG_SUBSYS_MAX) - 1) <<
71 FI_LOG_SUBSYS_OFFSET),
72 // FI_LOG_PROV_MASK = (((1 << (64 - FI_LOG_PROV_OFFSET)) - 1) <<
73 // FI_LOG_PROV_OFFSET)
74 };
75
76 #define FI_LOG_TAG(prov, level, subsys) \
77 (((uint64_t) prov << FI_LOG_PROV_OFFSET) | \
78 ((uint64_t) (1 << (subsys + FI_LOG_SUBSYS_OFFSET))) | \
79 ((uint64_t) (1 << level)))
80
81 uint64_t log_mask;
82 struct fi_filter prov_log_filter;
83
84 static pid_t pid;
85
fi_convert_log_str(const char * value)86 static int fi_convert_log_str(const char *value)
87 {
88 int i;
89
90 if (!value)
91 return -1;
92
93 for (i = 0; log_levels[i]; i++) {
94 if (!strcasecmp(value, log_levels[i]))
95 return i;
96 }
97 return 0;
98 }
99
fi_log_init(void)100 void fi_log_init(void)
101 {
102 struct fi_filter subsys_filter;
103 int level, i;
104 char *levelstr = NULL, *provstr = NULL, *subsysstr = NULL;
105
106 fi_param_define(NULL, "log_level", FI_PARAM_STRING,
107 "Specify logging level: warn, trace, info, debug (default: warn)");
108 fi_param_get_str(NULL, "log_level", &levelstr);
109 level = fi_convert_log_str(levelstr);
110 if (level >= 0)
111 log_mask = ((1 << (level + 1)) - 1);
112
113 fi_param_define(NULL, "log_prov", FI_PARAM_STRING,
114 "Specify specific provider to log (default: all)");
115 fi_param_get_str(NULL, "log_prov", &provstr);
116 ofi_create_filter(&prov_log_filter, provstr);
117
118 fi_param_define(NULL, "log_subsys", FI_PARAM_STRING,
119 "Specify specific subsystem to log (default: all)");
120 fi_param_get_str(NULL, "log_subsys", &subsysstr);
121 ofi_create_filter(&subsys_filter, subsysstr);
122 for (i = 0; i < FI_LOG_SUBSYS_MAX; i++) {
123 if (!ofi_apply_filter(&subsys_filter, log_subsys[i]))
124 log_mask |= (1ULL << (i + FI_LOG_SUBSYS_OFFSET));
125 }
126 ofi_free_filter(&subsys_filter);
127 pid = getpid();
128 }
129
fi_log_fini(void)130 void fi_log_fini(void)
131 {
132 ofi_free_filter(&prov_log_filter);
133 }
134
135 __attribute__((visibility ("default"),EXTERNALLY_VISIBLE))
DEFAULT_SYMVER_PRE(fi_log_enabled)136 int DEFAULT_SYMVER_PRE(fi_log_enabled)(const struct fi_provider *prov,
137 enum fi_log_level level,
138 enum fi_log_subsys subsys)
139 {
140 struct fi_prov_context *ctx;
141
142 ctx = (struct fi_prov_context *) &prov->context;
143 return ((FI_LOG_TAG(ctx->disable_logging, level, subsys) & log_mask) ==
144 FI_LOG_TAG(ctx->disable_logging, level, subsys));
145 }
146 DEFAULT_SYMVER(fi_log_enabled_, fi_log_enabled, FABRIC_1.0);
147
148 __attribute__((visibility ("default"),EXTERNALLY_VISIBLE))
DEFAULT_SYMVER_PRE(fi_log)149 void DEFAULT_SYMVER_PRE(fi_log)(const struct fi_provider *prov, enum fi_log_level level,
150 enum fi_log_subsys subsys, const char *func, int line,
151 const char *fmt, ...)
152 {
153 char buf[1024];
154 int size;
155
156 va_list vargs;
157
158 size = snprintf(buf, sizeof(buf), "%s:%d:%s:%s:%s():%d<%s> ", PACKAGE,
159 pid, prov->name, log_subsys[subsys], func, line,
160 log_levels[level]);
161
162 va_start(vargs, fmt);
163 vsnprintf(buf + size, sizeof(buf) - size, fmt, vargs);
164 va_end(vargs);
165
166 fprintf(stderr, "%s", buf);
167 }
168 DEFAULT_SYMVER(fi_log_, fi_log, FABRIC_1.0);
169