1c757249aSShailabh Nagar /* taskstats_kern.h - kernel header for per-task statistics interface
2c757249aSShailabh Nagar  *
3c757249aSShailabh Nagar  * Copyright (C) Shailabh Nagar, IBM Corp. 2006
4c757249aSShailabh Nagar  *           (C) Balbir Singh,   IBM Corp. 2006
5c757249aSShailabh Nagar  */
6c757249aSShailabh Nagar 
7c757249aSShailabh Nagar #ifndef _LINUX_TASKSTATS_KERN_H
8c757249aSShailabh Nagar #define _LINUX_TASKSTATS_KERN_H
9c757249aSShailabh Nagar 
10c757249aSShailabh Nagar #include <linux/taskstats.h>
11c757249aSShailabh Nagar #include <linux/sched.h>
12c8924363SShailabh Nagar #include <net/genetlink.h>
13c757249aSShailabh Nagar 
14c757249aSShailabh Nagar enum {
15c757249aSShailabh Nagar 	TASKSTATS_MSG_UNICAST,		/* send data only to requester */
16c757249aSShailabh Nagar 	TASKSTATS_MSG_MULTICAST,	/* send data to a group */
17c757249aSShailabh Nagar };
18c757249aSShailabh Nagar 
19c757249aSShailabh Nagar #ifdef CONFIG_TASKSTATS
20c757249aSShailabh Nagar extern kmem_cache_t *taskstats_cache;
216f44993fSShailabh Nagar extern struct mutex taskstats_exit_mutex;
22c757249aSShailabh Nagar 
23c8924363SShailabh Nagar static inline int taskstats_has_listeners(void)
24c8924363SShailabh Nagar {
25c8924363SShailabh Nagar 	if (!genl_sock)
26c8924363SShailabh Nagar 		return 0;
27c8924363SShailabh Nagar 	return netlink_has_listeners(genl_sock, TASKSTATS_LISTEN_GROUP);
28c8924363SShailabh Nagar }
29c8924363SShailabh Nagar 
30c8924363SShailabh Nagar 
31ad4ecbcbSShailabh Nagar static inline void taskstats_exit_alloc(struct taskstats **ptidstats)
32c757249aSShailabh Nagar {
33c8924363SShailabh Nagar 	*ptidstats = NULL;
34c8924363SShailabh Nagar 	if (taskstats_has_listeners())
35c757249aSShailabh Nagar 		*ptidstats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
36c757249aSShailabh Nagar }
37c757249aSShailabh Nagar 
38ad4ecbcbSShailabh Nagar static inline void taskstats_exit_free(struct taskstats *tidstats)
39c757249aSShailabh Nagar {
40c757249aSShailabh Nagar 	if (tidstats)
41c757249aSShailabh Nagar 		kmem_cache_free(taskstats_cache, tidstats);
42c757249aSShailabh Nagar }
43c757249aSShailabh Nagar 
44ad4ecbcbSShailabh Nagar static inline void taskstats_tgid_init(struct signal_struct *sig)
45ad4ecbcbSShailabh Nagar {
46ad4ecbcbSShailabh Nagar 	spin_lock_init(&sig->stats_lock);
47ad4ecbcbSShailabh Nagar 	sig->stats = NULL;
48ad4ecbcbSShailabh Nagar }
49c757249aSShailabh Nagar 
50ad4ecbcbSShailabh Nagar static inline void taskstats_tgid_alloc(struct signal_struct *sig)
51ad4ecbcbSShailabh Nagar {
52ad4ecbcbSShailabh Nagar 	struct taskstats *stats;
53ad4ecbcbSShailabh Nagar 	unsigned long flags;
54ad4ecbcbSShailabh Nagar 
55ad4ecbcbSShailabh Nagar 	stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
56ad4ecbcbSShailabh Nagar 	if (!stats)
57ad4ecbcbSShailabh Nagar 		return;
58ad4ecbcbSShailabh Nagar 
59ad4ecbcbSShailabh Nagar 	spin_lock_irqsave(&sig->stats_lock, flags);
60ad4ecbcbSShailabh Nagar 	if (!sig->stats) {
61ad4ecbcbSShailabh Nagar 		sig->stats = stats;
62ad4ecbcbSShailabh Nagar 		stats = NULL;
63ad4ecbcbSShailabh Nagar 	}
64ad4ecbcbSShailabh Nagar 	spin_unlock_irqrestore(&sig->stats_lock, flags);
65ad4ecbcbSShailabh Nagar 
66ad4ecbcbSShailabh Nagar 	if (stats)
67ad4ecbcbSShailabh Nagar 		kmem_cache_free(taskstats_cache, stats);
68ad4ecbcbSShailabh Nagar }
69ad4ecbcbSShailabh Nagar 
70ad4ecbcbSShailabh Nagar static inline void taskstats_tgid_free(struct signal_struct *sig)
71ad4ecbcbSShailabh Nagar {
72ad4ecbcbSShailabh Nagar 	struct taskstats *stats = NULL;
73ad4ecbcbSShailabh Nagar 	unsigned long flags;
74ad4ecbcbSShailabh Nagar 
75ad4ecbcbSShailabh Nagar 	spin_lock_irqsave(&sig->stats_lock, flags);
76ad4ecbcbSShailabh Nagar 	if (sig->stats) {
77ad4ecbcbSShailabh Nagar 		stats = sig->stats;
78ad4ecbcbSShailabh Nagar 		sig->stats = NULL;
79ad4ecbcbSShailabh Nagar 	}
80ad4ecbcbSShailabh Nagar 	spin_unlock_irqrestore(&sig->stats_lock, flags);
81ad4ecbcbSShailabh Nagar 	if (stats)
82ad4ecbcbSShailabh Nagar 		kmem_cache_free(taskstats_cache, stats);
83ad4ecbcbSShailabh Nagar }
84ad4ecbcbSShailabh Nagar 
85ad4ecbcbSShailabh Nagar extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int);
86ad4ecbcbSShailabh Nagar extern void taskstats_init_early(void);
87ad4ecbcbSShailabh Nagar extern void taskstats_tgid_alloc(struct signal_struct *);
88c757249aSShailabh Nagar #else
89ad4ecbcbSShailabh Nagar static inline void taskstats_exit_alloc(struct taskstats **ptidstats)
90c757249aSShailabh Nagar {}
91ad4ecbcbSShailabh Nagar static inline void taskstats_exit_free(struct taskstats *ptidstats)
92c757249aSShailabh Nagar {}
93c757249aSShailabh Nagar static inline void taskstats_exit_send(struct task_struct *tsk,
94c757249aSShailabh Nagar 				       struct taskstats *tidstats,
95ad4ecbcbSShailabh Nagar 				       int group_dead)
96ad4ecbcbSShailabh Nagar {}
97ad4ecbcbSShailabh Nagar static inline void taskstats_tgid_init(struct signal_struct *sig)
98ad4ecbcbSShailabh Nagar {}
99ad4ecbcbSShailabh Nagar static inline void taskstats_tgid_alloc(struct signal_struct *sig)
100ad4ecbcbSShailabh Nagar {}
101ad4ecbcbSShailabh Nagar static inline void taskstats_tgid_free(struct signal_struct *sig)
102c757249aSShailabh Nagar {}
103c757249aSShailabh Nagar static inline void taskstats_init_early(void)
104c757249aSShailabh Nagar {}
105c757249aSShailabh Nagar #endif /* CONFIG_TASKSTATS */
106c757249aSShailabh Nagar 
107c757249aSShailabh Nagar #endif
108c757249aSShailabh Nagar 
109