Skip to content

Commit f008345

Browse files
Hridya Valsarajugregkh
authored andcommitted
binder: add a mount option to show global stats
Currently, all binder state and statistics live in debugfs. We need this information even when debugfs is not mounted. This patch adds the mount option 'stats' to enable a binderfs instance to have binder debug information present in the same. 'stats=global' will enable the global binder statistics. In the future, 'stats=local' will enable binder statistics local to the binderfs instance. The two modes 'global' and 'local' will be mutually exclusive. 'stats=global' option is only available for a binderfs instance mounted in the initial user namespace. An attempt to use the option to mount a binderfs instance in another user namespace will return an EPERM error. Signed-off-by: Hridya Valsaraju <[email protected]> Acked-by: Christian Brauner <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ca2864c commit f008345

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

drivers/android/binderfs.c

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,27 @@ static DEFINE_IDA(binderfs_minors);
5151
/**
5252
* binderfs_mount_opts - mount options for binderfs
5353
* @max: maximum number of allocatable binderfs binder devices
54+
* @stats_mode: enable binder stats in binderfs.
5455
*/
5556
struct binderfs_mount_opts {
5657
int max;
58+
int stats_mode;
5759
};
5860

5961
enum {
6062
Opt_max,
63+
Opt_stats_mode,
6164
Opt_err
6265
};
6366

67+
enum binderfs_stats_mode {
68+
STATS_NONE,
69+
STATS_GLOBAL,
70+
};
71+
6472
static const match_table_t tokens = {
6573
{ Opt_max, "max=%d" },
74+
{ Opt_stats_mode, "stats=%s" },
6675
{ Opt_err, NULL }
6776
};
6877

@@ -290,8 +299,9 @@ static void binderfs_evict_inode(struct inode *inode)
290299
static int binderfs_parse_mount_opts(char *data,
291300
struct binderfs_mount_opts *opts)
292301
{
293-
char *p;
302+
char *p, *stats;
294303
opts->max = BINDERFS_MAX_MINOR;
304+
opts->stats_mode = STATS_NONE;
295305

296306
while ((p = strsep(&data, ",")) != NULL) {
297307
substring_t args[MAX_OPT_ARGS];
@@ -311,6 +321,22 @@ static int binderfs_parse_mount_opts(char *data,
311321

312322
opts->max = max_devices;
313323
break;
324+
case Opt_stats_mode:
325+
if (!capable(CAP_SYS_ADMIN))
326+
return -EINVAL;
327+
328+
stats = match_strdup(&args[0]);
329+
if (!stats)
330+
return -ENOMEM;
331+
332+
if (strcmp(stats, "global") != 0) {
333+
kfree(stats);
334+
return -EINVAL;
335+
}
336+
337+
opts->stats_mode = STATS_GLOBAL;
338+
kfree(stats);
339+
break;
314340
default:
315341
pr_err("Invalid mount options\n");
316342
return -EINVAL;
@@ -322,8 +348,21 @@ static int binderfs_parse_mount_opts(char *data,
322348

323349
static int binderfs_remount(struct super_block *sb, int *flags, char *data)
324350
{
351+
int prev_stats_mode, ret;
325352
struct binderfs_info *info = sb->s_fs_info;
326-
return binderfs_parse_mount_opts(data, &info->mount_opts);
353+
354+
prev_stats_mode = info->mount_opts.stats_mode;
355+
ret = binderfs_parse_mount_opts(data, &info->mount_opts);
356+
if (ret)
357+
return ret;
358+
359+
if (prev_stats_mode != info->mount_opts.stats_mode) {
360+
pr_err("Binderfs stats mode cannot be changed during a remount\n");
361+
info->mount_opts.stats_mode = prev_stats_mode;
362+
return -EINVAL;
363+
}
364+
365+
return 0;
327366
}
328367

329368
static int binderfs_show_mount_opts(struct seq_file *seq, struct dentry *root)
@@ -333,6 +372,8 @@ static int binderfs_show_mount_opts(struct seq_file *seq, struct dentry *root)
333372
info = root->d_sb->s_fs_info;
334373
if (info->mount_opts.max <= BINDERFS_MAX_MINOR)
335374
seq_printf(seq, ",max=%d", info->mount_opts.max);
375+
if (info->mount_opts.stats_mode == STATS_GLOBAL)
376+
seq_printf(seq, ",stats=global");
336377

337378
return 0;
338379
}

0 commit comments

Comments
 (0)