f8f0a51dcc1e738727286b69e28f343ac43476e1
4 * LTTng Process ID trackering.
6 * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <linux/module.h>
24 #include <linux/slab.h>
25 #include <linux/err.h>
26 #include <linux/seq_file.h>
27 #include <linux/stringify.h>
28 #include <linux/rculist.h>
29 #include <linux/hash.h>
30 #include <linux/rcupdate.h>
32 #include "wrapper/tracepoint.h"
33 #include "lttng-events.h"
36 * Hash table is allocated and freed when there are no possible
37 * concurrent lookups (ensured by the alloc/free caller). However,
38 * there can be concurrent RCU lookups vs add/del operations.
40 * Concurrent updates of the PID hash table are forbidden: the caller
41 * must ensure mutual exclusion. This is currently done by holding the
42 * sessions_mutex across calls to create, destroy, add, and del
43 * functions of this API.
45 struct lttng_pid_hash_node
{
46 struct hlist_node hlist
;
51 * Lookup performed from RCU read-side critical section (RCU sched),
52 * protected by preemption off at the tracepoint call site.
53 * Return 1 if found, 0 if not found.
55 bool lttng_pid_tracker_lookup(struct lttng_pid_tracker
*lpf
, int pid
)
57 struct hlist_head
*head
;
58 struct lttng_pid_hash_node
*e
;
59 uint32_t hash
= hash_32(pid
, 32);
61 head
= &lpf
->pid_hash
[hash
& (LTTNG_PID_TABLE_SIZE
- 1)];
62 hlist_for_each_entry_rcu_notrace(e
, head
, hlist
) {
68 EXPORT_SYMBOL_GPL(lttng_pid_tracker_lookup
);
71 * Tracker add and del operations support concurrent RCU lookups.
73 int lttng_pid_tracker_add(struct lttng_pid_tracker
*lpf
, int pid
)
75 struct hlist_head
*head
;
76 struct lttng_pid_hash_node
*e
;
77 uint32_t hash
= hash_32(pid
, 32);
79 head
= &lpf
->pid_hash
[hash
& (LTTNG_PID_TABLE_SIZE
- 1)];
80 hlist_for_each_entry(e
, head
, hlist
) {
84 e
= kmalloc(sizeof(struct lttng_pid_hash_node
), GFP_KERNEL
);
88 hlist_add_head_rcu(&e
->hlist
, head
);
93 void pid_tracker_del_node_rcu(struct lttng_pid_hash_node
*e
)
95 hlist_del_rcu(&e
->hlist
);
97 * We choose to use a heavyweight synchronize on removal here,
98 * since removal of a PID from the tracker mask is a rare
99 * operation, and we don't want to use more cache lines than
100 * what we really need when doing the PID lookups, so we don't
101 * want to afford adding a rcu_head field to those pid hash
109 * This removal is only used on destroy, so it does not need to support
110 * concurrent RCU lookups.
113 void pid_tracker_del_node(struct lttng_pid_hash_node
*e
)
115 hlist_del(&e
->hlist
);
119 int lttng_pid_tracker_del(struct lttng_pid_tracker
*lpf
, int pid
)
121 struct hlist_head
*head
;
122 struct lttng_pid_hash_node
*e
;
123 uint32_t hash
= hash_32(pid
, 32);
125 head
= &lpf
->pid_hash
[hash
& (LTTNG_PID_TABLE_SIZE
- 1)];
127 * No need of _safe iteration, because we stop traversal as soon
128 * as we remove the entry.
130 hlist_for_each_entry(e
, head
, hlist
) {
132 pid_tracker_del_node_rcu(e
);
136 return -ENOENT
; /* Not found */
139 struct lttng_pid_tracker
*lttng_pid_tracker_create(void)
141 return kzalloc(sizeof(struct lttng_pid_tracker
), GFP_KERNEL
);
144 void lttng_pid_tracker_destroy(struct lttng_pid_tracker
*lpf
)
148 for (i
= 0; i
< LTTNG_PID_TABLE_SIZE
; i
++) {
149 struct hlist_head
*head
= &lpf
->pid_hash
[i
];
150 struct lttng_pid_hash_node
*e
;
151 struct hlist_node
*tmp
;
153 hlist_for_each_entry_safe(e
, tmp
, head
, hlist
)
154 pid_tracker_del_node(e
);
This page took 0.035365 seconds and 4 git commands to generate.