Skip to content

Commit 61803e9

Browse files
Daeho JeongJaegeuk Kim
authored andcommitted
f2fs: fix iostat related lock protection
Made iostat related locks safe to be called from irq context again. Cc: <[email protected]> Fixes: a1e09b0 ("f2fs: use iomap for direct I/O") Signed-off-by: Daeho Jeong <[email protected]> Reviewed-by: Stanley Chu <[email protected]> Tested-by: Eddie Huang <[email protected]> Reviewed-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent 4cde00d commit 61803e9

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

fs/f2fs/iostat.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ static inline void __record_iostat_latency(struct f2fs_sb_info *sbi)
9191
unsigned int cnt;
9292
struct f2fs_iostat_latency iostat_lat[MAX_IO_TYPE][NR_PAGE_TYPE];
9393
struct iostat_lat_info *io_lat = sbi->iostat_io_lat;
94+
unsigned long flags;
9495

95-
spin_lock_bh(&sbi->iostat_lat_lock);
96+
spin_lock_irqsave(&sbi->iostat_lat_lock, flags);
9697
for (idx = 0; idx < MAX_IO_TYPE; idx++) {
9798
for (io = 0; io < NR_PAGE_TYPE; io++) {
9899
cnt = io_lat->bio_cnt[idx][io];
@@ -106,7 +107,7 @@ static inline void __record_iostat_latency(struct f2fs_sb_info *sbi)
106107
io_lat->bio_cnt[idx][io] = 0;
107108
}
108109
}
109-
spin_unlock_bh(&sbi->iostat_lat_lock);
110+
spin_unlock_irqrestore(&sbi->iostat_lat_lock, flags);
110111

111112
trace_f2fs_iostat_latency(sbi, iostat_lat);
112113
}
@@ -115,14 +116,15 @@ static inline void f2fs_record_iostat(struct f2fs_sb_info *sbi)
115116
{
116117
unsigned long long iostat_diff[NR_IO_TYPE];
117118
int i;
119+
unsigned long flags;
118120

119121
if (time_is_after_jiffies(sbi->iostat_next_period))
120122
return;
121123

122124
/* Need double check under the lock */
123-
spin_lock_bh(&sbi->iostat_lock);
125+
spin_lock_irqsave(&sbi->iostat_lock, flags);
124126
if (time_is_after_jiffies(sbi->iostat_next_period)) {
125-
spin_unlock_bh(&sbi->iostat_lock);
127+
spin_unlock_irqrestore(&sbi->iostat_lock, flags);
126128
return;
127129
}
128130
sbi->iostat_next_period = jiffies +
@@ -133,7 +135,7 @@ static inline void f2fs_record_iostat(struct f2fs_sb_info *sbi)
133135
sbi->prev_rw_iostat[i];
134136
sbi->prev_rw_iostat[i] = sbi->rw_iostat[i];
135137
}
136-
spin_unlock_bh(&sbi->iostat_lock);
138+
spin_unlock_irqrestore(&sbi->iostat_lock, flags);
137139

138140
trace_f2fs_iostat(sbi, iostat_diff);
139141

@@ -145,25 +147,27 @@ void f2fs_reset_iostat(struct f2fs_sb_info *sbi)
145147
struct iostat_lat_info *io_lat = sbi->iostat_io_lat;
146148
int i;
147149

148-
spin_lock_bh(&sbi->iostat_lock);
150+
spin_lock_irq(&sbi->iostat_lock);
149151
for (i = 0; i < NR_IO_TYPE; i++) {
150152
sbi->rw_iostat[i] = 0;
151153
sbi->prev_rw_iostat[i] = 0;
152154
}
153-
spin_unlock_bh(&sbi->iostat_lock);
155+
spin_unlock_irq(&sbi->iostat_lock);
154156

155-
spin_lock_bh(&sbi->iostat_lat_lock);
157+
spin_lock_irq(&sbi->iostat_lat_lock);
156158
memset(io_lat, 0, sizeof(struct iostat_lat_info));
157-
spin_unlock_bh(&sbi->iostat_lat_lock);
159+
spin_unlock_irq(&sbi->iostat_lat_lock);
158160
}
159161

160162
void f2fs_update_iostat(struct f2fs_sb_info *sbi,
161163
enum iostat_type type, unsigned long long io_bytes)
162164
{
165+
unsigned long flags;
166+
163167
if (!sbi->iostat_enable)
164168
return;
165169

166-
spin_lock_bh(&sbi->iostat_lock);
170+
spin_lock_irqsave(&sbi->iostat_lock, flags);
167171
sbi->rw_iostat[type] += io_bytes;
168172

169173
if (type == APP_BUFFERED_IO || type == APP_DIRECT_IO)
@@ -172,7 +176,7 @@ void f2fs_update_iostat(struct f2fs_sb_info *sbi,
172176
if (type == APP_BUFFERED_READ_IO || type == APP_DIRECT_READ_IO)
173177
sbi->rw_iostat[APP_READ_IO] += io_bytes;
174178

175-
spin_unlock_bh(&sbi->iostat_lock);
179+
spin_unlock_irqrestore(&sbi->iostat_lock, flags);
176180

177181
f2fs_record_iostat(sbi);
178182
}
@@ -185,6 +189,7 @@ static inline void __update_iostat_latency(struct bio_iostat_ctx *iostat_ctx,
185189
struct f2fs_sb_info *sbi = iostat_ctx->sbi;
186190
struct iostat_lat_info *io_lat = sbi->iostat_io_lat;
187191
int idx;
192+
unsigned long flags;
188193

189194
if (!sbi->iostat_enable)
190195
return;
@@ -202,12 +207,12 @@ static inline void __update_iostat_latency(struct bio_iostat_ctx *iostat_ctx,
202207
idx = WRITE_ASYNC_IO;
203208
}
204209

205-
spin_lock_bh(&sbi->iostat_lat_lock);
210+
spin_lock_irqsave(&sbi->iostat_lat_lock, flags);
206211
io_lat->sum_lat[idx][iotype] += ts_diff;
207212
io_lat->bio_cnt[idx][iotype]++;
208213
if (ts_diff > io_lat->peak_lat[idx][iotype])
209214
io_lat->peak_lat[idx][iotype] = ts_diff;
210-
spin_unlock_bh(&sbi->iostat_lat_lock);
215+
spin_unlock_irqrestore(&sbi->iostat_lat_lock, flags);
211216
}
212217

213218
void iostat_update_and_unbind_ctx(struct bio *bio, int rw)

0 commit comments

Comments
 (0)