+static
+struct lttng_counter_transport *lttng_counter_transport_find(const char *name)
+{
+ struct lttng_counter_transport *transport;
+
+ list_for_each_entry(transport, <tng_counter_transport_list, node) {
+ if (!strcmp(transport->name, name))
+ return transport;
+ }
+ return NULL;
+}
+
+struct lttng_counter *lttng_kernel_counter_create(
+ const char *counter_transport_name,
+ size_t number_dimensions, const size_t *dimensions_sizes)
+{
+ struct lttng_counter *counter = NULL;
+ struct lttng_counter_transport *counter_transport = NULL;
+
+ counter_transport = lttng_counter_transport_find(counter_transport_name);
+ if (!counter_transport) {
+ printk(KERN_WARNING "LTTng: counter transport %s not found.\n",
+ counter_transport_name);
+ goto notransport;
+ }
+ if (!try_module_get(counter_transport->owner)) {
+ printk(KERN_WARNING "LTTng: Can't lock counter transport module.\n");
+ goto notransport;
+ }
+
+ counter = lttng_kvzalloc(sizeof(struct lttng_counter), GFP_KERNEL);
+ if (!counter)
+ goto nomem;
+
+ /* Create event notifier error counter. */
+ counter->ops = &counter_transport->ops;
+ counter->transport = counter_transport;
+
+ counter->counter = counter->ops->counter_create(
+ number_dimensions, dimensions_sizes, 0);
+ if (!counter->counter) {
+ goto create_error;
+ }
+
+ return counter;
+
+create_error:
+ lttng_kvfree(counter);
+nomem:
+ if (counter_transport)
+ module_put(counter_transport->owner);
+notransport:
+ return NULL;
+}
+