0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 #include <linux/slab.h>
0065
0066 #include "rv.h"
0067
0068
0069
0070
0071 static LIST_HEAD(rv_reactors_list);
0072
0073 static struct rv_reactor_def *get_reactor_rdef_by_name(char *name)
0074 {
0075 struct rv_reactor_def *r;
0076
0077 list_for_each_entry(r, &rv_reactors_list, list) {
0078 if (strcmp(name, r->reactor->name) == 0)
0079 return r;
0080 }
0081 return NULL;
0082 }
0083
0084
0085
0086
0087 static int reactors_show(struct seq_file *m, void *p)
0088 {
0089 struct rv_reactor_def *rea_def = p;
0090
0091 seq_printf(m, "%s\n", rea_def->reactor->name);
0092 return 0;
0093 }
0094
0095 static void reactors_stop(struct seq_file *m, void *p)
0096 {
0097 mutex_unlock(&rv_interface_lock);
0098 }
0099
0100 static void *reactors_start(struct seq_file *m, loff_t *pos)
0101 {
0102 mutex_lock(&rv_interface_lock);
0103 return seq_list_start(&rv_reactors_list, *pos);
0104 }
0105
0106 static void *reactors_next(struct seq_file *m, void *p, loff_t *pos)
0107 {
0108 return seq_list_next(p, &rv_reactors_list, pos);
0109 }
0110
0111
0112
0113
0114 static const struct seq_operations available_reactors_seq_ops = {
0115 .start = reactors_start,
0116 .next = reactors_next,
0117 .stop = reactors_stop,
0118 .show = reactors_show
0119 };
0120
0121
0122
0123
0124 static int available_reactors_open(struct inode *inode, struct file *file)
0125 {
0126 return seq_open(file, &available_reactors_seq_ops);
0127 };
0128
0129 static const struct file_operations available_reactors_ops = {
0130 .open = available_reactors_open,
0131 .read = seq_read,
0132 .llseek = seq_lseek,
0133 .release = seq_release
0134 };
0135
0136
0137
0138
0139 static int monitor_reactor_show(struct seq_file *m, void *p)
0140 {
0141 struct rv_monitor_def *mdef = m->private;
0142 struct rv_reactor_def *rdef = p;
0143
0144 if (mdef->rdef == rdef)
0145 seq_printf(m, "[%s]\n", rdef->reactor->name);
0146 else
0147 seq_printf(m, "%s\n", rdef->reactor->name);
0148 return 0;
0149 }
0150
0151
0152
0153
0154 static const struct seq_operations monitor_reactors_seq_ops = {
0155 .start = reactors_start,
0156 .next = reactors_next,
0157 .stop = reactors_stop,
0158 .show = monitor_reactor_show
0159 };
0160
0161 static void monitor_swap_reactors(struct rv_monitor_def *mdef, struct rv_reactor_def *rdef,
0162 bool reacting)
0163 {
0164 bool monitor_enabled;
0165
0166
0167 if (mdef->rdef == rdef)
0168 return;
0169
0170 monitor_enabled = mdef->monitor->enabled;
0171 if (monitor_enabled)
0172 rv_disable_monitor(mdef);
0173
0174
0175 mdef->rdef->counter--;
0176 rdef->counter++;
0177
0178 mdef->rdef = rdef;
0179 mdef->reacting = reacting;
0180 mdef->monitor->react = rdef->reactor->react;
0181
0182 if (monitor_enabled)
0183 rv_enable_monitor(mdef);
0184 }
0185
0186 static ssize_t
0187 monitor_reactors_write(struct file *file, const char __user *user_buf,
0188 size_t count, loff_t *ppos)
0189 {
0190 char buff[MAX_RV_REACTOR_NAME_SIZE + 2];
0191 struct rv_monitor_def *mdef;
0192 struct rv_reactor_def *rdef;
0193 struct seq_file *seq_f;
0194 int retval = -EINVAL;
0195 bool enable;
0196 char *ptr;
0197 int len;
0198
0199 if (count < 1 || count > MAX_RV_REACTOR_NAME_SIZE + 1)
0200 return -EINVAL;
0201
0202 memset(buff, 0, sizeof(buff));
0203
0204 retval = simple_write_to_buffer(buff, sizeof(buff) - 1, ppos, user_buf, count);
0205 if (retval < 0)
0206 return -EFAULT;
0207
0208 ptr = strim(buff);
0209
0210 len = strlen(ptr);
0211 if (!len)
0212 return count;
0213
0214
0215
0216
0217 seq_f = file->private_data;
0218 mdef = seq_f->private;
0219
0220 mutex_lock(&rv_interface_lock);
0221
0222 retval = -EINVAL;
0223
0224 list_for_each_entry(rdef, &rv_reactors_list, list) {
0225 if (strcmp(ptr, rdef->reactor->name) != 0)
0226 continue;
0227
0228 if (rdef == get_reactor_rdef_by_name("nop"))
0229 enable = false;
0230 else
0231 enable = true;
0232
0233 monitor_swap_reactors(mdef, rdef, enable);
0234
0235 retval = count;
0236 break;
0237 }
0238
0239 mutex_unlock(&rv_interface_lock);
0240
0241 return retval;
0242 }
0243
0244
0245
0246
0247 static int monitor_reactors_open(struct inode *inode, struct file *file)
0248 {
0249 struct rv_monitor_def *mdef = inode->i_private;
0250 struct seq_file *seq_f;
0251 int ret;
0252
0253 ret = seq_open(file, &monitor_reactors_seq_ops);
0254 if (ret < 0)
0255 return ret;
0256
0257
0258
0259
0260 seq_f = file->private_data;
0261
0262
0263
0264
0265 seq_f->private = mdef;
0266
0267 return 0;
0268 };
0269
0270 static const struct file_operations monitor_reactors_ops = {
0271 .open = monitor_reactors_open,
0272 .read = seq_read,
0273 .llseek = seq_lseek,
0274 .release = seq_release,
0275 .write = monitor_reactors_write
0276 };
0277
0278 static int __rv_register_reactor(struct rv_reactor *reactor)
0279 {
0280 struct rv_reactor_def *r;
0281
0282 list_for_each_entry(r, &rv_reactors_list, list) {
0283 if (strcmp(reactor->name, r->reactor->name) == 0) {
0284 pr_info("Reactor %s is already registered\n", reactor->name);
0285 return -EINVAL;
0286 }
0287 }
0288
0289 r = kzalloc(sizeof(struct rv_reactor_def), GFP_KERNEL);
0290 if (!r)
0291 return -ENOMEM;
0292
0293 r->reactor = reactor;
0294 r->counter = 0;
0295
0296 list_add_tail(&r->list, &rv_reactors_list);
0297
0298 return 0;
0299 }
0300
0301
0302
0303
0304
0305
0306
0307 int rv_register_reactor(struct rv_reactor *reactor)
0308 {
0309 int retval = 0;
0310
0311 if (strlen(reactor->name) >= MAX_RV_REACTOR_NAME_SIZE) {
0312 pr_info("Reactor %s has a name longer than %d\n",
0313 reactor->name, MAX_RV_MONITOR_NAME_SIZE);
0314 return -EINVAL;
0315 }
0316
0317 mutex_lock(&rv_interface_lock);
0318 retval = __rv_register_reactor(reactor);
0319 mutex_unlock(&rv_interface_lock);
0320 return retval;
0321 }
0322
0323
0324
0325
0326
0327
0328
0329 int rv_unregister_reactor(struct rv_reactor *reactor)
0330 {
0331 struct rv_reactor_def *ptr, *next;
0332 int ret = 0;
0333
0334 mutex_lock(&rv_interface_lock);
0335
0336 list_for_each_entry_safe(ptr, next, &rv_reactors_list, list) {
0337 if (strcmp(reactor->name, ptr->reactor->name) == 0) {
0338
0339 if (!ptr->counter) {
0340 list_del(&ptr->list);
0341 } else {
0342 printk(KERN_WARNING
0343 "rv: the rv_reactor %s is in use by %d monitor(s)\n",
0344 ptr->reactor->name, ptr->counter);
0345 printk(KERN_WARNING "rv: the rv_reactor %s cannot be removed\n",
0346 ptr->reactor->name);
0347 ret = -EBUSY;
0348 break;
0349 }
0350 }
0351 }
0352
0353 mutex_unlock(&rv_interface_lock);
0354 return ret;
0355 }
0356
0357
0358
0359
0360 static bool __read_mostly reacting_on;
0361
0362
0363
0364
0365
0366
0367 bool rv_reacting_on(void)
0368 {
0369
0370 smp_rmb();
0371 return READ_ONCE(reacting_on);
0372 }
0373
0374 static ssize_t reacting_on_read_data(struct file *filp,
0375 char __user *user_buf,
0376 size_t count, loff_t *ppos)
0377 {
0378 char *buff;
0379
0380 buff = rv_reacting_on() ? "1\n" : "0\n";
0381
0382 return simple_read_from_buffer(user_buf, count, ppos, buff, strlen(buff)+1);
0383 }
0384
0385 static void turn_reacting_off(void)
0386 {
0387 WRITE_ONCE(reacting_on, false);
0388
0389 smp_wmb();
0390 }
0391
0392 static void turn_reacting_on(void)
0393 {
0394 WRITE_ONCE(reacting_on, true);
0395
0396 smp_wmb();
0397 }
0398
0399 static ssize_t reacting_on_write_data(struct file *filp, const char __user *user_buf,
0400 size_t count, loff_t *ppos)
0401 {
0402 int retval;
0403 bool val;
0404
0405 retval = kstrtobool_from_user(user_buf, count, &val);
0406 if (retval)
0407 return retval;
0408
0409 mutex_lock(&rv_interface_lock);
0410
0411 if (val)
0412 turn_reacting_on();
0413 else
0414 turn_reacting_off();
0415
0416
0417
0418
0419
0420 tracepoint_synchronize_unregister();
0421
0422 mutex_unlock(&rv_interface_lock);
0423
0424 return count;
0425 }
0426
0427 static const struct file_operations reacting_on_fops = {
0428 .open = simple_open,
0429 .llseek = no_llseek,
0430 .write = reacting_on_write_data,
0431 .read = reacting_on_read_data,
0432 };
0433
0434
0435
0436
0437
0438
0439
0440 int reactor_populate_monitor(struct rv_monitor_def *mdef)
0441 {
0442 struct dentry *tmp;
0443
0444 tmp = rv_create_file("reactors", RV_MODE_WRITE, mdef->root_d, mdef, &monitor_reactors_ops);
0445 if (!tmp)
0446 return -ENOMEM;
0447
0448
0449
0450
0451 mdef->rdef = get_reactor_rdef_by_name("nop");
0452 mdef->rdef->counter++;
0453 mdef->reacting = false;
0454
0455 return 0;
0456 }
0457
0458
0459
0460
0461
0462 void reactor_cleanup_monitor(struct rv_monitor_def *mdef)
0463 {
0464 lockdep_assert_held(&rv_interface_lock);
0465 mdef->rdef->counter--;
0466 WARN_ON_ONCE(mdef->rdef->counter < 0);
0467 }
0468
0469
0470
0471
0472 static void rv_nop_reaction(char *msg)
0473 {
0474 }
0475
0476 static struct rv_reactor rv_nop = {
0477 .name = "nop",
0478 .description = "no-operation reactor: do nothing.",
0479 .react = rv_nop_reaction
0480 };
0481
0482 int init_rv_reactors(struct dentry *root_dir)
0483 {
0484 struct dentry *available, *reacting;
0485 int retval;
0486
0487 available = rv_create_file("available_reactors", RV_MODE_READ, root_dir, NULL,
0488 &available_reactors_ops);
0489 if (!available)
0490 goto out_err;
0491
0492 reacting = rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL, &reacting_on_fops);
0493 if (!reacting)
0494 goto rm_available;
0495
0496 retval = __rv_register_reactor(&rv_nop);
0497 if (retval)
0498 goto rm_reacting;
0499
0500 turn_reacting_on();
0501
0502 return 0;
0503
0504 rm_reacting:
0505 rv_remove(reacting);
0506 rm_available:
0507 rv_remove(available);
0508 out_err:
0509 return -ENOMEM;
0510 }