main.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* General filesystem local caching manager
  3. *
  4. * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
  5. * Written by David Howells (dhowells@redhat.com)
  6. */
  7. #define FSCACHE_DEBUG_LEVEL CACHE
  8. #include <linux/module.h>
  9. #include <linux/init.h>
  10. #include <linux/sched.h>
  11. #include <linux/completion.h>
  12. #include <linux/slab.h>
  13. #include <linux/seq_file.h>
  14. #define CREATE_TRACE_POINTS
  15. #include "internal.h"
  16. MODULE_DESCRIPTION("FS Cache Manager");
  17. MODULE_AUTHOR("Red Hat, Inc.");
  18. MODULE_LICENSE("GPL");
  19. unsigned fscache_defer_lookup = 1;
  20. module_param_named(defer_lookup, fscache_defer_lookup, uint,
  21. S_IWUSR | S_IRUGO);
  22. MODULE_PARM_DESC(fscache_defer_lookup,
  23. "Defer cookie lookup to background thread");
  24. unsigned fscache_defer_create = 1;
  25. module_param_named(defer_create, fscache_defer_create, uint,
  26. S_IWUSR | S_IRUGO);
  27. MODULE_PARM_DESC(fscache_defer_create,
  28. "Defer cookie creation to background thread");
  29. unsigned fscache_debug;
  30. module_param_named(debug, fscache_debug, uint,
  31. S_IWUSR | S_IRUGO);
  32. MODULE_PARM_DESC(fscache_debug,
  33. "FS-Cache debugging mask");
  34. struct kobject *fscache_root;
  35. struct workqueue_struct *fscache_object_wq;
  36. struct workqueue_struct *fscache_op_wq;
  37. DEFINE_PER_CPU(wait_queue_head_t, fscache_object_cong_wait);
  38. /* these values serve as lower bounds, will be adjusted in fscache_init() */
  39. static unsigned fscache_object_max_active = 4;
  40. static unsigned fscache_op_max_active = 2;
  41. #ifdef CONFIG_SYSCTL
  42. static struct ctl_table_header *fscache_sysctl_header;
  43. static int fscache_max_active_sysctl(struct ctl_table *table, int write,
  44. void *buffer, size_t *lenp, loff_t *ppos)
  45. {
  46. struct workqueue_struct **wqp = table->extra1;
  47. unsigned int *datap = table->data;
  48. int ret;
  49. ret = proc_dointvec(table, write, buffer, lenp, ppos);
  50. if (ret == 0)
  51. workqueue_set_max_active(*wqp, *datap);
  52. return ret;
  53. }
  54. static struct ctl_table fscache_sysctls[] = {
  55. {
  56. .procname = "object_max_active",
  57. .data = &fscache_object_max_active,
  58. .maxlen = sizeof(unsigned),
  59. .mode = 0644,
  60. .proc_handler = fscache_max_active_sysctl,
  61. .extra1 = &fscache_object_wq,
  62. },
  63. {
  64. .procname = "operation_max_active",
  65. .data = &fscache_op_max_active,
  66. .maxlen = sizeof(unsigned),
  67. .mode = 0644,
  68. .proc_handler = fscache_max_active_sysctl,
  69. .extra1 = &fscache_op_wq,
  70. },
  71. {}
  72. };
  73. static struct ctl_table fscache_sysctls_root[] = {
  74. {
  75. .procname = "fscache",
  76. .mode = 0555,
  77. .child = fscache_sysctls,
  78. },
  79. {}
  80. };
  81. #endif
  82. /*
  83. * Mixing scores (in bits) for (7,20):
  84. * Input delta: 1-bit 2-bit
  85. * 1 round: 330.3 9201.6
  86. * 2 rounds: 1246.4 25475.4
  87. * 3 rounds: 1907.1 31295.1
  88. * 4 rounds: 2042.3 31718.6
  89. * Perfect: 2048 31744
  90. * (32*64) (32*31/2 * 64)
  91. */
  92. #define HASH_MIX(x, y, a) \
  93. ( x ^= (a), \
  94. y ^= x, x = rol32(x, 7),\
  95. x += y, y = rol32(y,20),\
  96. y *= 9 )
  97. static inline unsigned int fold_hash(unsigned long x, unsigned long y)
  98. {
  99. /* Use arch-optimized multiply if one exists */
  100. return __hash_32(y ^ __hash_32(x));
  101. }
  102. /*
  103. * Generate a hash. This is derived from full_name_hash(), but we want to be
  104. * sure it is arch independent and that it doesn't change as bits of the
  105. * computed hash value might appear on disk. The caller also guarantees that
  106. * the hashed data will be a series of aligned 32-bit words.
  107. */
  108. unsigned int fscache_hash(unsigned int salt, unsigned int *data, unsigned int n)
  109. {
  110. unsigned int a, x = 0, y = salt;
  111. for (; n; n--) {
  112. a = *data++;
  113. HASH_MIX(x, y, a);
  114. }
  115. return fold_hash(x, y);
  116. }
  117. /*
  118. * initialise the fs caching module
  119. */
  120. static int __init fscache_init(void)
  121. {
  122. unsigned int nr_cpus = num_possible_cpus();
  123. unsigned int cpu;
  124. int ret;
  125. fscache_object_max_active =
  126. clamp_val(nr_cpus,
  127. fscache_object_max_active, WQ_UNBOUND_MAX_ACTIVE);
  128. ret = -ENOMEM;
  129. fscache_object_wq = alloc_workqueue("fscache_object", WQ_UNBOUND,
  130. fscache_object_max_active);
  131. if (!fscache_object_wq)
  132. goto error_object_wq;
  133. fscache_op_max_active =
  134. clamp_val(fscache_object_max_active / 2,
  135. fscache_op_max_active, WQ_UNBOUND_MAX_ACTIVE);
  136. ret = -ENOMEM;
  137. fscache_op_wq = alloc_workqueue("fscache_operation", WQ_UNBOUND,
  138. fscache_op_max_active);
  139. if (!fscache_op_wq)
  140. goto error_op_wq;
  141. for_each_possible_cpu(cpu)
  142. init_waitqueue_head(&per_cpu(fscache_object_cong_wait, cpu));
  143. ret = fscache_proc_init();
  144. if (ret < 0)
  145. goto error_proc;
  146. #ifdef CONFIG_SYSCTL
  147. ret = -ENOMEM;
  148. fscache_sysctl_header = register_sysctl_table(fscache_sysctls_root);
  149. if (!fscache_sysctl_header)
  150. goto error_sysctl;
  151. #endif
  152. fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar",
  153. sizeof(struct fscache_cookie),
  154. 0, 0, NULL);
  155. if (!fscache_cookie_jar) {
  156. pr_notice("Failed to allocate a cookie jar\n");
  157. ret = -ENOMEM;
  158. goto error_cookie_jar;
  159. }
  160. fscache_root = kobject_create_and_add("fscache", kernel_kobj);
  161. if (!fscache_root)
  162. goto error_kobj;
  163. pr_notice("Loaded\n");
  164. return 0;
  165. error_kobj:
  166. kmem_cache_destroy(fscache_cookie_jar);
  167. error_cookie_jar:
  168. #ifdef CONFIG_SYSCTL
  169. unregister_sysctl_table(fscache_sysctl_header);
  170. error_sysctl:
  171. #endif
  172. fscache_proc_cleanup();
  173. error_proc:
  174. destroy_workqueue(fscache_op_wq);
  175. error_op_wq:
  176. destroy_workqueue(fscache_object_wq);
  177. error_object_wq:
  178. return ret;
  179. }
  180. fs_initcall(fscache_init);
  181. /*
  182. * clean up on module removal
  183. */
  184. static void __exit fscache_exit(void)
  185. {
  186. _enter("");
  187. kobject_put(fscache_root);
  188. kmem_cache_destroy(fscache_cookie_jar);
  189. #ifdef CONFIG_SYSCTL
  190. unregister_sysctl_table(fscache_sysctl_header);
  191. #endif
  192. fscache_proc_cleanup();
  193. destroy_workqueue(fscache_op_wq);
  194. destroy_workqueue(fscache_object_wq);
  195. pr_notice("Unloaded\n");
  196. }
  197. module_exit(fscache_exit);