Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0a020d41 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

lib: introduce initial implementation of object aggregation manager



This lib tracks objects which could be of two types:
1) root object
2) nested object - with a "delta" which differentiates it from
                   the associated root object
The objects are tracked by a hashtable and reference-counted. User is
responsible of implementing callbacks to create/destroy root entity
related to each root object and callback to create/destroy nested object
delta.

Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7dc5a0ee
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -10679,6 +10679,14 @@ L: linux-nfc@lists.01.org (moderated for non-subscribers)
S:	Supported
F:	drivers/nfc/nxp-nci

OBJAGG
M:	Jiri Pirko <jiri@mellanox.com>
L:	netdev@vger.kernel.org
S:	Supported
F:	lib/objagg.c
F:	lib/test_objagg.c
F:	include/linux/objagg.h

OBJTOOL
M:	Josh Poimboeuf <jpoimboe@redhat.com>
M:	Peter Zijlstra <peterz@infradead.org>

include/linux/objagg.h

0 → 100644
+46 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
/* Copyright (c) 2018 Mellanox Technologies. All rights reserved */

#ifndef _OBJAGG_H
#define _OBJAGG_H

struct objagg_ops {
	size_t obj_size;
	void * (*delta_create)(void *priv, void *parent_obj, void *obj);
	void (*delta_destroy)(void *priv, void *delta_priv);
	void * (*root_create)(void *priv, void *obj);
	void (*root_destroy)(void *priv, void *root_priv);
};

struct objagg;
struct objagg_obj;

const void *objagg_obj_root_priv(const struct objagg_obj *objagg_obj);
const void *objagg_obj_delta_priv(const struct objagg_obj *objagg_obj);
const void *objagg_obj_raw(const struct objagg_obj *objagg_obj);

struct objagg_obj *objagg_obj_get(struct objagg *objagg, void *obj);
void objagg_obj_put(struct objagg *objagg, struct objagg_obj *objagg_obj);
struct objagg *objagg_create(const struct objagg_ops *ops, void *priv);
void objagg_destroy(struct objagg *objagg);

struct objagg_obj_stats {
	unsigned int user_count;
	unsigned int delta_user_count; /* includes delta object users */
};

struct objagg_obj_stats_info {
	struct objagg_obj_stats stats;
	struct objagg_obj *objagg_obj; /* associated object */
	bool is_root;
};

struct objagg_stats {
	unsigned int stats_info_count;
	struct objagg_obj_stats_info stats_info[];
};

const struct objagg_stats *objagg_stats_get(struct objagg *objagg);
void objagg_stats_put(const struct objagg_stats *objagg_stats);

#endif
+228 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
/* Copyright (c) 2018 Mellanox Technologies. All rights reserved */

#undef TRACE_SYSTEM
#define TRACE_SYSTEM objagg

#if !defined(__TRACE_OBJAGG_H) || defined(TRACE_HEADER_MULTI_READ)
#define __TRACE_OBJAGG_H

#include <linux/tracepoint.h>

struct objagg;
struct objagg_obj;

TRACE_EVENT(objagg_create,
	TP_PROTO(const struct objagg *objagg),

	TP_ARGS(objagg),

	TP_STRUCT__entry(
		__field(const void *, objagg)
	),

	TP_fast_assign(
		__entry->objagg = objagg;
	),

	TP_printk("objagg %p", __entry->objagg)
);

TRACE_EVENT(objagg_destroy,
	TP_PROTO(const struct objagg *objagg),

	TP_ARGS(objagg),

	TP_STRUCT__entry(
		__field(const void *, objagg)
	),

	TP_fast_assign(
		__entry->objagg = objagg;
	),

	TP_printk("objagg %p", __entry->objagg)
);

TRACE_EVENT(objagg_obj_create,
	TP_PROTO(const struct objagg *objagg,
		 const struct objagg_obj *obj),

	TP_ARGS(objagg, obj),

	TP_STRUCT__entry(
		__field(const void *, objagg)
		__field(const void *, obj)
	),

	TP_fast_assign(
		__entry->objagg = objagg;
		__entry->obj = obj;
	),

	TP_printk("objagg %p, obj %p", __entry->objagg, __entry->obj)
);

TRACE_EVENT(objagg_obj_destroy,
	TP_PROTO(const struct objagg *objagg,
		 const struct objagg_obj *obj),

	TP_ARGS(objagg, obj),

	TP_STRUCT__entry(
		__field(const void *, objagg)
		__field(const void *, obj)
	),

	TP_fast_assign(
		__entry->objagg = objagg;
		__entry->obj = obj;
	),

	TP_printk("objagg %p, obj %p", __entry->objagg, __entry->obj)
);

TRACE_EVENT(objagg_obj_get,
	TP_PROTO(const struct objagg *objagg,
		 const struct objagg_obj *obj,
		 unsigned int refcount),

	TP_ARGS(objagg, obj, refcount),

	TP_STRUCT__entry(
		__field(const void *, objagg)
		__field(const void *, obj)
		__field(unsigned int, refcount)
	),

	TP_fast_assign(
		__entry->objagg = objagg;
		__entry->obj = obj;
		__entry->refcount = refcount;
	),

	TP_printk("objagg %p, obj %p, refcount %u",
		  __entry->objagg, __entry->obj, __entry->refcount)
);

TRACE_EVENT(objagg_obj_put,
	TP_PROTO(const struct objagg *objagg,
		 const struct objagg_obj *obj,
		 unsigned int refcount),

	TP_ARGS(objagg, obj, refcount),

	TP_STRUCT__entry(
		__field(const void *, objagg)
		__field(const void *, obj)
		__field(unsigned int, refcount)
	),

	TP_fast_assign(
		__entry->objagg = objagg;
		__entry->obj = obj;
		__entry->refcount = refcount;
	),

	TP_printk("objagg %p, obj %p, refcount %u",
		  __entry->objagg, __entry->obj, __entry->refcount)
);

TRACE_EVENT(objagg_obj_parent_assign,
	TP_PROTO(const struct objagg *objagg,
		 const struct objagg_obj *obj,
		 const struct objagg_obj *parent,
		 unsigned int parent_refcount),

	TP_ARGS(objagg, obj, parent, parent_refcount),

	TP_STRUCT__entry(
		__field(const void *, objagg)
		__field(const void *, obj)
		__field(const void *, parent)
		__field(unsigned int, parent_refcount)
	),

	TP_fast_assign(
		__entry->objagg = objagg;
		__entry->obj = obj;
		__entry->parent = parent;
		__entry->parent_refcount = parent_refcount;
	),

	TP_printk("objagg %p, obj %p, parent %p, parent_refcount %u",
		  __entry->objagg, __entry->obj,
		  __entry->parent, __entry->parent_refcount)
);

TRACE_EVENT(objagg_obj_parent_unassign,
	TP_PROTO(const struct objagg *objagg,
		 const struct objagg_obj *obj,
		 const struct objagg_obj *parent,
		 unsigned int parent_refcount),

	TP_ARGS(objagg, obj, parent, parent_refcount),

	TP_STRUCT__entry(
		__field(const void *, objagg)
		__field(const void *, obj)
		__field(const void *, parent)
		__field(unsigned int, parent_refcount)
	),

	TP_fast_assign(
		__entry->objagg = objagg;
		__entry->obj = obj;
		__entry->parent = parent;
		__entry->parent_refcount = parent_refcount;
	),

	TP_printk("objagg %p, obj %p, parent %p, parent_refcount %u",
		  __entry->objagg, __entry->obj,
		  __entry->parent, __entry->parent_refcount)
);

TRACE_EVENT(objagg_obj_root_create,
	TP_PROTO(const struct objagg *objagg,
		 const struct objagg_obj *obj),

	TP_ARGS(objagg, obj),

	TP_STRUCT__entry(
		__field(const void *, objagg)
		__field(const void *, obj)
	),

	TP_fast_assign(
		__entry->objagg = objagg;
		__entry->obj = obj;
	),

	TP_printk("objagg %p, obj %p",
		  __entry->objagg, __entry->obj)
);

TRACE_EVENT(objagg_obj_root_destroy,
	TP_PROTO(const struct objagg *objagg,
		 const struct objagg_obj *obj),

	TP_ARGS(objagg, obj),

	TP_STRUCT__entry(
		__field(const void *, objagg)
		__field(const void *, obj)
	),

	TP_fast_assign(
		__entry->objagg = objagg;
		__entry->obj = obj;
	),

	TP_printk("objagg %p, obj %p",
		  __entry->objagg, __entry->obj)
);

#endif /* __TRACE_OBJAGG_H */

/* This part must be outside protection */
#include <trace/define_trace.h>
+3 −0
Original line number Diff line number Diff line
@@ -624,3 +624,6 @@ config GENERIC_LIB_CMPDI2

config GENERIC_LIB_UCMPDI2
	bool

config OBJAGG
	tristate "objagg" if COMPILE_TEST
+10 −0
Original line number Diff line number Diff line
@@ -1976,6 +1976,16 @@ config TEST_MEMCAT_P

	  If unsure, say N.

config TEST_OBJAGG
	tristate "Perform selftest on object aggreration manager"
	default n
	depends on OBJAGG
	help
	  Enable this option to test object aggregation manager on boot
	  (or module load).

	  If unsure, say N.

endif # RUNTIME_TESTING_MENU

config MEMTEST
Loading