call_kern.cocci 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /// Find functions that refer to GFP_KERNEL but are called with locks held.
  3. //# The proposed change of converting the GFP_KERNEL is not necessarily the
  4. //# correct one. It may be desired to unlock the lock, or to not call the
  5. //# function under the lock in the first place.
  6. ///
  7. // Confidence: Moderate
  8. // Copyright: (C) 2012 Nicolas Palix.
  9. // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
  10. // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
  11. // URL: https://coccinelle.gitlabpages.inria.fr/website
  12. // Comments:
  13. // Options: --no-includes --include-headers
  14. virtual patch
  15. virtual context
  16. virtual org
  17. virtual report
  18. @gfp exists@
  19. identifier fn;
  20. position p;
  21. @@
  22. fn(...) {
  23. ... when != read_unlock_irq(...)
  24. when != write_unlock_irq(...)
  25. when != read_unlock_irqrestore(...)
  26. when != write_unlock_irqrestore(...)
  27. when != spin_unlock(...)
  28. when != spin_unlock_irq(...)
  29. when != spin_unlock_irqrestore(...)
  30. when != local_irq_enable(...)
  31. when any
  32. GFP_KERNEL@p
  33. ... when any
  34. }
  35. @locked exists@
  36. identifier gfp.fn;
  37. position p1,p2;
  38. @@
  39. (
  40. read_lock_irq@p1
  41. |
  42. write_lock_irq@p1
  43. |
  44. read_lock_irqsave@p1
  45. |
  46. write_lock_irqsave@p1
  47. |
  48. spin_lock@p1
  49. |
  50. spin_trylock@p1
  51. |
  52. spin_lock_irq@p1
  53. |
  54. spin_lock_irqsave@p1
  55. |
  56. local_irq_disable@p1
  57. )
  58. (...)
  59. ... when != read_unlock_irq(...)
  60. when != write_unlock_irq(...)
  61. when != read_unlock_irqrestore(...)
  62. when != write_unlock_irqrestore(...)
  63. when != spin_unlock(...)
  64. when != spin_unlock_irq(...)
  65. when != spin_unlock_irqrestore(...)
  66. when != local_irq_enable(...)
  67. fn@p2(...)
  68. @depends on locked && patch@
  69. position gfp.p;
  70. @@
  71. - GFP_KERNEL@p
  72. + GFP_ATOMIC
  73. @depends on locked && !patch@
  74. position gfp.p;
  75. @@
  76. * GFP_KERNEL@p
  77. @script:python depends on !patch && org@
  78. p << gfp.p;
  79. fn << gfp.fn;
  80. p1 << locked.p1;
  81. p2 << locked.p2;
  82. @@
  83. cocci.print_main("lock",p1)
  84. cocci.print_secs("call",p2)
  85. cocci.print_secs("GFP_KERNEL",p)
  86. @script:python depends on !patch && report@
  87. p << gfp.p;
  88. fn << gfp.fn;
  89. p1 << locked.p1;
  90. p2 << locked.p2;
  91. @@
  92. msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line)
  93. coccilib.report.print_report(p[0], msg)