Skip to content

Commit 172703b

Browse files
Matt Flemingtorvalds
authored andcommitted
mm: delete non-atomic mm counter implementation
The problem with having two different types of counters is that developers adding new code need to keep in mind whether it's safe to use both the atomic and non-atomic implementations. For example, when adding new callers of the *_mm_counter() functions a developer needs to ensure that those paths are always executed with page_table_lock held, in case we're using the non-atomic implementation of mm counters. Hugh Dickins introduced the atomic mm counters in commit f412ac0 ("[PATCH] mm: fix rss and mmlist locking"). When asked why he left the non-atomic counters around he said, | The only reason was to avoid adding costly atomic operations into a | configuration that had no need for them there: the page_table_lock | sufficed. | | Certainly it would be simpler just to delete the non-atomic variant. | | And I think it's fair to say that any configuration on which we're | measuring performance to that degree (rather than "does it boot fast?" | type measurements), would already be going the split ptlocks route. Removing the non-atomic counters eases the maintenance burden because developers no longer have to mindful of the two implementations when using *_mm_counter(). Note that all architectures provide a means of atomically updating atomic_long_t variables, even if they have to revert to the generic spinlock implementation because they don't support 64-bit atomic instructions (see lib/atomic64.c). Signed-off-by: Matt Fleming <matt.fleming@linux.intel.com> Acked-by: Dave Hansen <dave@linux.vnet.ibm.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Hugh Dickins <hughd@google.com> Cc: Christoph Lameter <cl@linux-foundation.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent a197b59 commit 172703b

File tree

2 files changed

+10
-43
lines changed

2 files changed

+10
-43
lines changed

include/linux/mm.h

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,65 +1053,35 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
10531053
/*
10541054
* per-process(per-mm_struct) statistics.
10551055
*/
1056-
#if defined(SPLIT_RSS_COUNTING)
1057-
/*
1058-
* The mm counters are not protected by its page_table_lock,
1059-
* so must be incremented atomically.
1060-
*/
10611056
static inline void set_mm_counter(struct mm_struct *mm, int member, long value)
10621057
{
10631058
atomic_long_set(&mm->rss_stat.count[member], value);
10641059
}
10651060

1061+
#if defined(SPLIT_RSS_COUNTING)
10661062
unsigned long get_mm_counter(struct mm_struct *mm, int member);
1067-
1068-
static inline void add_mm_counter(struct mm_struct *mm, int member, long value)
1069-
{
1070-
atomic_long_add(value, &mm->rss_stat.count[member]);
1071-
}
1072-
1073-
static inline void inc_mm_counter(struct mm_struct *mm, int member)
1074-
{
1075-
atomic_long_inc(&mm->rss_stat.count[member]);
1076-
}
1077-
1078-
static inline void dec_mm_counter(struct mm_struct *mm, int member)
1079-
{
1080-
atomic_long_dec(&mm->rss_stat.count[member]);
1081-
}
1082-
1083-
#else /* !USE_SPLIT_PTLOCKS */
1084-
/*
1085-
* The mm counters are protected by its page_table_lock,
1086-
* so can be incremented directly.
1087-
*/
1088-
static inline void set_mm_counter(struct mm_struct *mm, int member, long value)
1089-
{
1090-
mm->rss_stat.count[member] = value;
1091-
}
1092-
1063+
#else
10931064
static inline unsigned long get_mm_counter(struct mm_struct *mm, int member)
10941065
{
1095-
return mm->rss_stat.count[member];
1066+
return atomic_long_read(&mm->rss_stat.count[member]);
10961067
}
1068+
#endif
10971069

10981070
static inline void add_mm_counter(struct mm_struct *mm, int member, long value)
10991071
{
1100-
mm->rss_stat.count[member] += value;
1072+
atomic_long_add(value, &mm->rss_stat.count[member]);
11011073
}
11021074

11031075
static inline void inc_mm_counter(struct mm_struct *mm, int member)
11041076
{
1105-
mm->rss_stat.count[member]++;
1077+
atomic_long_inc(&mm->rss_stat.count[member]);
11061078
}
11071079

11081080
static inline void dec_mm_counter(struct mm_struct *mm, int member)
11091081
{
1110-
mm->rss_stat.count[member]--;
1082+
atomic_long_dec(&mm->rss_stat.count[member]);
11111083
}
11121084

1113-
#endif /* !USE_SPLIT_PTLOCKS */
1114-
11151085
static inline unsigned long get_mm_rss(struct mm_struct *mm)
11161086
{
11171087
return get_mm_counter(mm, MM_FILEPAGES) +

include/linux/mm_types.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,19 +204,16 @@ enum {
204204

205205
#if USE_SPLIT_PTLOCKS && defined(CONFIG_MMU)
206206
#define SPLIT_RSS_COUNTING
207-
struct mm_rss_stat {
208-
atomic_long_t count[NR_MM_COUNTERS];
209-
};
210207
/* per-thread cached information, */
211208
struct task_rss_stat {
212209
int events; /* for synchronization threshold */
213210
int count[NR_MM_COUNTERS];
214211
};
215-
#else /* !USE_SPLIT_PTLOCKS */
212+
#endif /* USE_SPLIT_PTLOCKS */
213+
216214
struct mm_rss_stat {
217-
unsigned long count[NR_MM_COUNTERS];
215+
atomic_long_t count[NR_MM_COUNTERS];
218216
};
219-
#endif /* !USE_SPLIT_PTLOCKS */
220217

221218
struct mm_struct {
222219
struct vm_area_struct * mmap; /* list of VMAs */

0 commit comments

Comments
 (0)