amap_smart.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef _SDFAT_AMAP_H
  18. #define _SDFAT_AMAP_H
  19. #include <linux/fs.h>
  20. #include <linux/list.h>
  21. #include <linux/rbtree.h>
  22. /* AMAP Configuration Variable */
  23. #define SMART_ALLOC_N_HOT_AU (5)
  24. /* Allocating Destination (for smart allocator):
  25. * moved to sdfat.h
  26. */
  27. /*
  28. * #define ALLOC_COLD_ALIGNED (1)
  29. * #define ALLOC_COLD_PACKING (2)
  30. * #define ALLOC_COLD_SEQ (4)
  31. */
  32. /* Minimum sectors for support AMAP create */
  33. #define AMAP_MIN_SUPPORT_SECTORS (1048576)
  34. #define amap_add_hot_au(amap, au) amap_insert_to_list(au, &amap->slist_hot)
  35. /* singly linked list */
  36. struct slist_head {
  37. struct slist_head *next;
  38. struct slist_head *head;
  39. };
  40. /* AU entry type */
  41. typedef struct __AU_INFO_T {
  42. uint16_t idx; /* the index of the AU (0, 1, 2, ... ) */
  43. uint16_t free_clusters; /* # of available cluster */
  44. union {
  45. struct list_head head;
  46. struct slist_head shead;/* singly linked list head for hot list */
  47. };
  48. } AU_INFO_T;
  49. /* Allocation Target AU */
  50. typedef struct __TARGET_AU_T {
  51. AU_INFO_T *au; /* Working AU */
  52. uint16_t idx; /* Intra-AU cluster index */
  53. uint16_t clu_to_skip; /* Clusters to skip */
  54. } TARGET_AU_T;
  55. /* AMAP free-clusters-based node */
  56. typedef struct {
  57. struct list_head head; /* the list of AUs */
  58. } FCLU_NODE_T;
  59. /* AMAP options */
  60. typedef struct {
  61. unsigned int packing_ratio; /* Tunable packing ratio */
  62. unsigned int au_size; /* AU size in sectors */
  63. unsigned int au_align_factor; /* Hidden sectors % au_size */
  64. } AMAP_OPT_T;
  65. typedef struct __AMAP_T {
  66. spinlock_t amap_lock; /* obsolete */
  67. struct super_block *sb;
  68. int n_au;
  69. int n_clean_au, n_full_au;
  70. int clu_align_bias;
  71. uint16_t clusters_per_au;
  72. AU_INFO_T **au_table; /* An array of AU_INFO entries */
  73. AMAP_OPT_T option;
  74. /* Size-based AU management pool (cold) */
  75. FCLU_NODE_T *fclu_nodes; /* An array of listheads */
  76. int fclu_order; /* Page order that fclu_nodes needs */
  77. int fclu_hint; /* maximum # of free clusters in an AU */
  78. /* Hot AU list */
  79. unsigned int total_fclu_hot; /* Free clusters in hot list */
  80. struct slist_head slist_hot; /* Hot AU list */
  81. /* Ignored AU list */
  82. struct slist_head slist_ignored;
  83. /* Allocator variables (keep 2 AUs at maximum) */
  84. TARGET_AU_T cur_cold;
  85. TARGET_AU_T cur_hot;
  86. int n_need_packing;
  87. } AMAP_T;
  88. /* AU table */
  89. #define N_AU_PER_TABLE (int)(PAGE_SIZE / sizeof(AU_INFO_T))
  90. #define GET_AU(amap, i_AU) (amap->au_table[(i_AU) / N_AU_PER_TABLE] + ((i_AU) % N_AU_PER_TABLE))
  91. //#define MAX_CLU_PER_AU (int)(PAGE_SIZE / sizeof(FCLU_NODE_T))
  92. #define MAX_CLU_PER_AU (1024)
  93. /* Cold AU bucket <-> # of freeclusters */
  94. #define NODE_CLEAN(amap) (&amap->fclu_nodes[amap->clusters_per_au - 1])
  95. #define NODE(fclu, amap) (&amap->fclu_nodes[fclu - 1])
  96. #define FREE_CLUSTERS(node, amap) ((int)(node - amap->fclu_nodes) + 1)
  97. /* AU status */
  98. #define MAGIC_WORKING ((struct slist_head *)0xFFFF5091)
  99. #define IS_AU_HOT(au, amap) (au->shead.head == &amap->slist_hot)
  100. #define IS_AU_IGNORED(au, amap) (au->shead.head == &amap->slist_ignored)
  101. #define IS_AU_WORKING(au, amap) (au->shead.head == MAGIC_WORKING)
  102. #define SET_AU_WORKING(au) (au->shead.head = MAGIC_WORKING)
  103. /* AU <-> cluster */
  104. #define i_AU_of_CLU(amap, clu) ((amap->clu_align_bias + clu) / amap->clusters_per_au)
  105. #define CLU_of_i_AU(amap, i_au, idx) \
  106. ((uint32_t)(i_au) * (uint32_t)amap->clusters_per_au + (idx) - amap->clu_align_bias)
  107. /*
  108. * NOTE : AMAP internal functions are moved to core.h
  109. */
  110. #endif /* _SDFAT_AMAP_H */