Contents of /trunk/kernel-alx/patches-5.4/0105-5.4.6-all-fixes.patch
Parent Directory | Revision Log
Revision 3486 -
(show annotations)
(download)
Mon May 11 14:36:00 2020 UTC (4 years, 4 months ago) by niro
File size: 115349 byte(s)
Mon May 11 14:36:00 2020 UTC (4 years, 4 months ago) by niro
File size: 115349 byte(s)
-linux-5.4.6
1 | diff --git a/Makefile b/Makefile |
2 | index 0f6e72d5e4f1..20ec7c20279e 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,7 +1,7 @@ |
6 | # SPDX-License-Identifier: GPL-2.0 |
7 | VERSION = 5 |
8 | PATCHLEVEL = 4 |
9 | -SUBLEVEL = 5 |
10 | +SUBLEVEL = 6 |
11 | EXTRAVERSION = |
12 | NAME = Kleptomaniac Octopus |
13 | |
14 | diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts |
15 | index 0e159c884f97..1aeac33b0d34 100644 |
16 | --- a/arch/arm/boot/dts/s3c6410-mini6410.dts |
17 | +++ b/arch/arm/boot/dts/s3c6410-mini6410.dts |
18 | @@ -165,6 +165,10 @@ |
19 | }; |
20 | }; |
21 | |
22 | +&clocks { |
23 | + clocks = <&fin_pll>; |
24 | +}; |
25 | + |
26 | &sdhci0 { |
27 | pinctrl-names = "default"; |
28 | pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; |
29 | diff --git a/arch/arm/boot/dts/s3c6410-smdk6410.dts b/arch/arm/boot/dts/s3c6410-smdk6410.dts |
30 | index a9a5689dc462..3bf6c450a26e 100644 |
31 | --- a/arch/arm/boot/dts/s3c6410-smdk6410.dts |
32 | +++ b/arch/arm/boot/dts/s3c6410-smdk6410.dts |
33 | @@ -69,6 +69,10 @@ |
34 | }; |
35 | }; |
36 | |
37 | +&clocks { |
38 | + clocks = <&fin_pll>; |
39 | +}; |
40 | + |
41 | &sdhci0 { |
42 | pinctrl-names = "default"; |
43 | pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; |
44 | diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S |
45 | index 67b763fea005..e3f34815c9da 100644 |
46 | --- a/arch/arm/mach-tegra/reset-handler.S |
47 | +++ b/arch/arm/mach-tegra/reset-handler.S |
48 | @@ -44,16 +44,16 @@ ENTRY(tegra_resume) |
49 | cmp r6, #TEGRA20 |
50 | beq 1f @ Yes |
51 | /* Clear the flow controller flags for this CPU. */ |
52 | - cpu_to_csr_reg r1, r0 |
53 | + cpu_to_csr_reg r3, r0 |
54 | mov32 r2, TEGRA_FLOW_CTRL_BASE |
55 | - ldr r1, [r2, r1] |
56 | + ldr r1, [r2, r3] |
57 | /* Clear event & intr flag */ |
58 | orr r1, r1, \ |
59 | #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG |
60 | movw r0, #0x3FFD @ enable, cluster_switch, immed, bitmaps |
61 | @ & ext flags for CPU power mgnt |
62 | bic r1, r1, r0 |
63 | - str r1, [r2] |
64 | + str r1, [r2, r3] |
65 | 1: |
66 | |
67 | mov32 r9, 0xc09 |
68 | diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h |
69 | index 359ab40e935a..c90fb944f9d8 100644 |
70 | --- a/arch/xtensa/include/asm/syscall.h |
71 | +++ b/arch/xtensa/include/asm/syscall.h |
72 | @@ -51,7 +51,7 @@ static inline void syscall_set_return_value(struct task_struct *task, |
73 | struct pt_regs *regs, |
74 | int error, long val) |
75 | { |
76 | - regs->areg[0] = (long) error ? error : val; |
77 | + regs->areg[2] = (long) error ? error : val; |
78 | } |
79 | |
80 | #define SYSCALL_MAX_ARGS 6 |
81 | diff --git a/arch/xtensa/mm/kasan_init.c b/arch/xtensa/mm/kasan_init.c |
82 | index af7152560bc3..b771459778fe 100644 |
83 | --- a/arch/xtensa/mm/kasan_init.c |
84 | +++ b/arch/xtensa/mm/kasan_init.c |
85 | @@ -56,7 +56,9 @@ static void __init populate(void *start, void *end) |
86 | |
87 | for (k = 0; k < PTRS_PER_PTE; ++k, ++j) { |
88 | phys_addr_t phys = |
89 | - memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); |
90 | + memblock_phys_alloc_range(PAGE_SIZE, PAGE_SIZE, |
91 | + 0, |
92 | + MEMBLOCK_ALLOC_ANYWHERE); |
93 | |
94 | if (!phys) |
95 | panic("Failed to allocate page table page\n"); |
96 | diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c |
97 | index 59153d0aa890..b43f03620843 100644 |
98 | --- a/arch/xtensa/mm/tlb.c |
99 | +++ b/arch/xtensa/mm/tlb.c |
100 | @@ -216,6 +216,8 @@ static int check_tlb_entry(unsigned w, unsigned e, bool dtlb) |
101 | unsigned tlbidx = w | (e << PAGE_SHIFT); |
102 | unsigned r0 = dtlb ? |
103 | read_dtlb_virtual(tlbidx) : read_itlb_virtual(tlbidx); |
104 | + unsigned r1 = dtlb ? |
105 | + read_dtlb_translation(tlbidx) : read_itlb_translation(tlbidx); |
106 | unsigned vpn = (r0 & PAGE_MASK) | (e << PAGE_SHIFT); |
107 | unsigned pte = get_pte_for_vaddr(vpn); |
108 | unsigned mm_asid = (get_rasid_register() >> 8) & ASID_MASK; |
109 | @@ -231,8 +233,6 @@ static int check_tlb_entry(unsigned w, unsigned e, bool dtlb) |
110 | } |
111 | |
112 | if (tlb_asid == mm_asid) { |
113 | - unsigned r1 = dtlb ? read_dtlb_translation(tlbidx) : |
114 | - read_itlb_translation(tlbidx); |
115 | if ((pte ^ r1) & PAGE_MASK) { |
116 | pr_err("%cTLB: way: %u, entry: %u, mapping: %08x->%08x, PTE: %08x\n", |
117 | dtlb ? 'D' : 'I', w, e, r0, r1, pte); |
118 | diff --git a/block/bio.c b/block/bio.c |
119 | index b1170ec18464..43df756b68c4 100644 |
120 | --- a/block/bio.c |
121 | +++ b/block/bio.c |
122 | @@ -751,10 +751,12 @@ bool __bio_try_merge_page(struct bio *bio, struct page *page, |
123 | if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED))) |
124 | return false; |
125 | |
126 | - if (bio->bi_vcnt > 0 && !bio_full(bio, len)) { |
127 | + if (bio->bi_vcnt > 0) { |
128 | struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1]; |
129 | |
130 | if (page_is_mergeable(bv, page, len, off, same_page)) { |
131 | + if (bio->bi_iter.bi_size > UINT_MAX - len) |
132 | + return false; |
133 | bv->bv_len += len; |
134 | bio->bi_iter.bi_size += len; |
135 | return true; |
136 | diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c |
137 | index 25c5c071645b..91185db9a952 100644 |
138 | --- a/drivers/dma-buf/sync_file.c |
139 | +++ b/drivers/dma-buf/sync_file.c |
140 | @@ -221,7 +221,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, |
141 | a_fences = get_fences(a, &a_num_fences); |
142 | b_fences = get_fences(b, &b_num_fences); |
143 | if (a_num_fences > INT_MAX - b_num_fences) |
144 | - return NULL; |
145 | + goto err; |
146 | |
147 | num_fences = a_num_fences + b_num_fences; |
148 | |
149 | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |
150 | index b6e1d98ef01e..aef6c396bd58 100644 |
151 | --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |
152 | +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |
153 | @@ -77,6 +77,7 @@ struct amdgpu_gmc_fault { |
154 | struct amdgpu_vmhub { |
155 | uint32_t ctx0_ptb_addr_lo32; |
156 | uint32_t ctx0_ptb_addr_hi32; |
157 | + uint32_t vm_inv_eng0_sem; |
158 | uint32_t vm_inv_eng0_req; |
159 | uint32_t vm_inv_eng0_ack; |
160 | uint32_t vm_context0_cntl; |
161 | diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |
162 | index 53090eae0082..596722e79a26 100644 |
163 | --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |
164 | +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |
165 | @@ -1785,27 +1785,52 @@ static void gfx_v10_0_enable_gui_idle_interrupt(struct amdgpu_device *adev, |
166 | WREG32_SOC15(GC, 0, mmCP_INT_CNTL_RING0, tmp); |
167 | } |
168 | |
169 | -static void gfx_v10_0_init_csb(struct amdgpu_device *adev) |
170 | +static int gfx_v10_0_init_csb(struct amdgpu_device *adev) |
171 | { |
172 | + int r; |
173 | + |
174 | + if (adev->in_gpu_reset) { |
175 | + r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false); |
176 | + if (r) |
177 | + return r; |
178 | + |
179 | + r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, |
180 | + (void **)&adev->gfx.rlc.cs_ptr); |
181 | + if (!r) { |
182 | + adev->gfx.rlc.funcs->get_csb_buffer(adev, |
183 | + adev->gfx.rlc.cs_ptr); |
184 | + amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj); |
185 | + } |
186 | + |
187 | + amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); |
188 | + if (r) |
189 | + return r; |
190 | + } |
191 | + |
192 | /* csib */ |
193 | WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_HI, |
194 | adev->gfx.rlc.clear_state_gpu_addr >> 32); |
195 | WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_LO, |
196 | adev->gfx.rlc.clear_state_gpu_addr & 0xfffffffc); |
197 | WREG32_SOC15(GC, 0, mmRLC_CSIB_LENGTH, adev->gfx.rlc.clear_state_size); |
198 | + |
199 | + return 0; |
200 | } |
201 | |
202 | -static void gfx_v10_0_init_pg(struct amdgpu_device *adev) |
203 | +static int gfx_v10_0_init_pg(struct amdgpu_device *adev) |
204 | { |
205 | int i; |
206 | + int r; |
207 | |
208 | - gfx_v10_0_init_csb(adev); |
209 | + r = gfx_v10_0_init_csb(adev); |
210 | + if (r) |
211 | + return r; |
212 | |
213 | for (i = 0; i < adev->num_vmhubs; i++) |
214 | amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0); |
215 | |
216 | /* TODO: init power gating */ |
217 | - return; |
218 | + return 0; |
219 | } |
220 | |
221 | void gfx_v10_0_rlc_stop(struct amdgpu_device *adev) |
222 | @@ -1907,7 +1932,10 @@ static int gfx_v10_0_rlc_resume(struct amdgpu_device *adev) |
223 | r = gfx_v10_0_wait_for_rlc_autoload_complete(adev); |
224 | if (r) |
225 | return r; |
226 | - gfx_v10_0_init_pg(adev); |
227 | + |
228 | + r = gfx_v10_0_init_pg(adev); |
229 | + if (r) |
230 | + return r; |
231 | |
232 | /* enable RLC SRM */ |
233 | gfx_v10_0_rlc_enable_srm(adev); |
234 | @@ -1933,7 +1961,10 @@ static int gfx_v10_0_rlc_resume(struct amdgpu_device *adev) |
235 | return r; |
236 | } |
237 | |
238 | - gfx_v10_0_init_pg(adev); |
239 | + r = gfx_v10_0_init_pg(adev); |
240 | + if (r) |
241 | + return r; |
242 | + |
243 | adev->gfx.rlc.funcs->start(adev); |
244 | |
245 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) { |
246 | @@ -2400,7 +2431,7 @@ static int gfx_v10_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev) |
247 | return 0; |
248 | } |
249 | |
250 | -static void gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) |
251 | +static int gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) |
252 | { |
253 | int i; |
254 | u32 tmp = RREG32_SOC15(GC, 0, mmCP_ME_CNTL); |
255 | @@ -2413,7 +2444,17 @@ static void gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) |
256 | adev->gfx.gfx_ring[i].sched.ready = false; |
257 | } |
258 | WREG32_SOC15(GC, 0, mmCP_ME_CNTL, tmp); |
259 | - udelay(50); |
260 | + |
261 | + for (i = 0; i < adev->usec_timeout; i++) { |
262 | + if (RREG32_SOC15(GC, 0, mmCP_STAT) == 0) |
263 | + break; |
264 | + udelay(1); |
265 | + } |
266 | + |
267 | + if (i >= adev->usec_timeout) |
268 | + DRM_ERROR("failed to %s cp gfx\n", enable ? "unhalt" : "halt"); |
269 | + |
270 | + return 0; |
271 | } |
272 | |
273 | static int gfx_v10_0_cp_gfx_load_pfp_microcode(struct amdgpu_device *adev) |
274 | diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c |
275 | index 6ce37ce77d14..d6fbdc6c0548 100644 |
276 | --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c |
277 | +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c |
278 | @@ -365,6 +365,8 @@ void gfxhub_v1_0_init(struct amdgpu_device *adev) |
279 | hub->ctx0_ptb_addr_hi32 = |
280 | SOC15_REG_OFFSET(GC, 0, |
281 | mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); |
282 | + hub->vm_inv_eng0_sem = |
283 | + SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG0_SEM); |
284 | hub->vm_inv_eng0_req = |
285 | SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG0_REQ); |
286 | hub->vm_inv_eng0_ack = |
287 | diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c |
288 | index db10640a3b2f..fbe06c13a09c 100644 |
289 | --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c |
290 | +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c |
291 | @@ -350,6 +350,8 @@ void gfxhub_v2_0_init(struct amdgpu_device *adev) |
292 | hub->ctx0_ptb_addr_hi32 = |
293 | SOC15_REG_OFFSET(GC, 0, |
294 | mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); |
295 | + hub->vm_inv_eng0_sem = |
296 | + SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_SEM); |
297 | hub->vm_inv_eng0_req = |
298 | SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_REQ); |
299 | hub->vm_inv_eng0_ack = |
300 | diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c |
301 | index 5c7d5f73f54f..a7ba4c6cf7a1 100644 |
302 | --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c |
303 | +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c |
304 | @@ -235,6 +235,29 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, |
305 | const unsigned eng = 17; |
306 | unsigned int i; |
307 | |
308 | + spin_lock(&adev->gmc.invalidate_lock); |
309 | + /* |
310 | + * It may lose gpuvm invalidate acknowldege state across power-gating |
311 | + * off cycle, add semaphore acquire before invalidation and semaphore |
312 | + * release after invalidation to avoid entering power gated state |
313 | + * to WA the Issue |
314 | + */ |
315 | + |
316 | + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ |
317 | + if (vmhub == AMDGPU_MMHUB_0 || |
318 | + vmhub == AMDGPU_MMHUB_1) { |
319 | + for (i = 0; i < adev->usec_timeout; i++) { |
320 | + /* a read return value of 1 means semaphore acuqire */ |
321 | + tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng); |
322 | + if (tmp & 0x1) |
323 | + break; |
324 | + udelay(1); |
325 | + } |
326 | + |
327 | + if (i >= adev->usec_timeout) |
328 | + DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); |
329 | + } |
330 | + |
331 | WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); |
332 | |
333 | /* |
334 | @@ -254,6 +277,17 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, |
335 | udelay(1); |
336 | } |
337 | |
338 | + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ |
339 | + if (vmhub == AMDGPU_MMHUB_0 || |
340 | + vmhub == AMDGPU_MMHUB_1) |
341 | + /* |
342 | + * add semaphore release after invalidation, |
343 | + * write with 0 means semaphore release |
344 | + */ |
345 | + WREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng, 0); |
346 | + |
347 | + spin_unlock(&adev->gmc.invalidate_lock); |
348 | + |
349 | if (i < adev->usec_timeout) |
350 | return; |
351 | |
352 | @@ -338,6 +372,20 @@ static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, |
353 | uint32_t req = gmc_v10_0_get_invalidate_req(vmid, 0); |
354 | unsigned eng = ring->vm_inv_eng; |
355 | |
356 | + /* |
357 | + * It may lose gpuvm invalidate acknowldege state across power-gating |
358 | + * off cycle, add semaphore acquire before invalidation and semaphore |
359 | + * release after invalidation to avoid entering power gated state |
360 | + * to WA the Issue |
361 | + */ |
362 | + |
363 | + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ |
364 | + if (ring->funcs->vmhub == AMDGPU_MMHUB_0 || |
365 | + ring->funcs->vmhub == AMDGPU_MMHUB_1) |
366 | + /* a read return value of 1 means semaphore acuqire */ |
367 | + amdgpu_ring_emit_reg_wait(ring, |
368 | + hub->vm_inv_eng0_sem + eng, 0x1, 0x1); |
369 | + |
370 | amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 + (2 * vmid), |
371 | lower_32_bits(pd_addr)); |
372 | |
373 | @@ -348,6 +396,15 @@ static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, |
374 | hub->vm_inv_eng0_ack + eng, |
375 | req, 1 << vmid); |
376 | |
377 | + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ |
378 | + if (ring->funcs->vmhub == AMDGPU_MMHUB_0 || |
379 | + ring->funcs->vmhub == AMDGPU_MMHUB_1) |
380 | + /* |
381 | + * add semaphore release after invalidation, |
382 | + * write with 0 means semaphore release |
383 | + */ |
384 | + amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_sem + eng, 0); |
385 | + |
386 | return pd_addr; |
387 | } |
388 | |
389 | diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c |
390 | index f91337030dc0..d7caca042173 100644 |
391 | --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c |
392 | +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c |
393 | @@ -448,6 +448,24 @@ static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid, |
394 | return req; |
395 | } |
396 | |
397 | +/** |
398 | + * gmc_v9_0_use_invalidate_semaphore - judge whether to use semaphore |
399 | + * |
400 | + * @adev: amdgpu_device pointer |
401 | + * @vmhub: vmhub type |
402 | + * |
403 | + */ |
404 | +static bool gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev, |
405 | + uint32_t vmhub) |
406 | +{ |
407 | + return ((vmhub == AMDGPU_MMHUB_0 || |
408 | + vmhub == AMDGPU_MMHUB_1) && |
409 | + (!amdgpu_sriov_vf(adev)) && |
410 | + (!(adev->asic_type == CHIP_RAVEN && |
411 | + adev->rev_id < 0x8 && |
412 | + adev->pdev->device == 0x15d8))); |
413 | +} |
414 | + |
415 | /* |
416 | * GART |
417 | * VMID 0 is the physical GPU addresses as used by the kernel. |
418 | @@ -467,6 +485,7 @@ static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid, |
419 | static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, |
420 | uint32_t vmhub, uint32_t flush_type) |
421 | { |
422 | + bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub); |
423 | const unsigned eng = 17; |
424 | u32 j, tmp; |
425 | struct amdgpu_vmhub *hub; |
426 | @@ -491,6 +510,28 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, |
427 | } |
428 | |
429 | spin_lock(&adev->gmc.invalidate_lock); |
430 | + |
431 | + /* |
432 | + * It may lose gpuvm invalidate acknowldege state across power-gating |
433 | + * off cycle, add semaphore acquire before invalidation and semaphore |
434 | + * release after invalidation to avoid entering power gated state |
435 | + * to WA the Issue |
436 | + */ |
437 | + |
438 | + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ |
439 | + if (use_semaphore) { |
440 | + for (j = 0; j < adev->usec_timeout; j++) { |
441 | + /* a read return value of 1 means semaphore acuqire */ |
442 | + tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng); |
443 | + if (tmp & 0x1) |
444 | + break; |
445 | + udelay(1); |
446 | + } |
447 | + |
448 | + if (j >= adev->usec_timeout) |
449 | + DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); |
450 | + } |
451 | + |
452 | WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); |
453 | |
454 | /* |
455 | @@ -506,7 +547,17 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, |
456 | break; |
457 | udelay(1); |
458 | } |
459 | + |
460 | + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ |
461 | + if (use_semaphore) |
462 | + /* |
463 | + * add semaphore release after invalidation, |
464 | + * write with 0 means semaphore release |
465 | + */ |
466 | + WREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng, 0); |
467 | + |
468 | spin_unlock(&adev->gmc.invalidate_lock); |
469 | + |
470 | if (j < adev->usec_timeout) |
471 | return; |
472 | |
473 | @@ -516,11 +567,25 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, |
474 | static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, |
475 | unsigned vmid, uint64_t pd_addr) |
476 | { |
477 | + bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(ring->adev, ring->funcs->vmhub); |
478 | struct amdgpu_device *adev = ring->adev; |
479 | struct amdgpu_vmhub *hub = &adev->vmhub[ring->funcs->vmhub]; |
480 | uint32_t req = gmc_v9_0_get_invalidate_req(vmid, 0); |
481 | unsigned eng = ring->vm_inv_eng; |
482 | |
483 | + /* |
484 | + * It may lose gpuvm invalidate acknowldege state across power-gating |
485 | + * off cycle, add semaphore acquire before invalidation and semaphore |
486 | + * release after invalidation to avoid entering power gated state |
487 | + * to WA the Issue |
488 | + */ |
489 | + |
490 | + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ |
491 | + if (use_semaphore) |
492 | + /* a read return value of 1 means semaphore acuqire */ |
493 | + amdgpu_ring_emit_reg_wait(ring, |
494 | + hub->vm_inv_eng0_sem + eng, 0x1, 0x1); |
495 | + |
496 | amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 + (2 * vmid), |
497 | lower_32_bits(pd_addr)); |
498 | |
499 | @@ -531,6 +596,14 @@ static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, |
500 | hub->vm_inv_eng0_ack + eng, |
501 | req, 1 << vmid); |
502 | |
503 | + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ |
504 | + if (use_semaphore) |
505 | + /* |
506 | + * add semaphore release after invalidation, |
507 | + * write with 0 means semaphore release |
508 | + */ |
509 | + amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_sem + eng, 0); |
510 | + |
511 | return pd_addr; |
512 | } |
513 | |
514 | diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c |
515 | index 04cd4b6f95d4..641f1258f08d 100644 |
516 | --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c |
517 | +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c |
518 | @@ -418,6 +418,8 @@ void mmhub_v1_0_init(struct amdgpu_device *adev) |
519 | hub->ctx0_ptb_addr_hi32 = |
520 | SOC15_REG_OFFSET(MMHUB, 0, |
521 | mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); |
522 | + hub->vm_inv_eng0_sem = |
523 | + SOC15_REG_OFFSET(MMHUB, 0, mmVM_INVALIDATE_ENG0_SEM); |
524 | hub->vm_inv_eng0_req = |
525 | SOC15_REG_OFFSET(MMHUB, 0, mmVM_INVALIDATE_ENG0_REQ); |
526 | hub->vm_inv_eng0_ack = |
527 | diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c |
528 | index b39bea6f54e9..096bb883c29d 100644 |
529 | --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c |
530 | +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c |
531 | @@ -341,6 +341,8 @@ void mmhub_v2_0_init(struct amdgpu_device *adev) |
532 | hub->ctx0_ptb_addr_hi32 = |
533 | SOC15_REG_OFFSET(MMHUB, 0, |
534 | mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); |
535 | + hub->vm_inv_eng0_sem = |
536 | + SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_INVALIDATE_ENG0_SEM); |
537 | hub->vm_inv_eng0_req = |
538 | SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_INVALIDATE_ENG0_REQ); |
539 | hub->vm_inv_eng0_ack = |
540 | diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c |
541 | index 9ed178fa241c..fb161c83e409 100644 |
542 | --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c |
543 | +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c |
544 | @@ -502,6 +502,10 @@ void mmhub_v9_4_init(struct amdgpu_device *adev) |
545 | SOC15_REG_OFFSET(MMHUB, 0, |
546 | mmVML2VC0_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32) + |
547 | i * MMHUB_INSTANCE_REGISTER_OFFSET; |
548 | + hub[i]->vm_inv_eng0_sem = |
549 | + SOC15_REG_OFFSET(MMHUB, 0, |
550 | + mmVML2VC0_VM_INVALIDATE_ENG0_SEM) + |
551 | + i * MMHUB_INSTANCE_REGISTER_OFFSET; |
552 | hub[i]->vm_inv_eng0_req = |
553 | SOC15_REG_OFFSET(MMHUB, 0, |
554 | mmVML2VC0_VM_INVALIDATE_ENG0_REQ) + |
555 | diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.h b/drivers/gpu/drm/amd/amdgpu/soc15.h |
556 | index a3dde0c31f57..a1d4ea69a284 100644 |
557 | --- a/drivers/gpu/drm/amd/amdgpu/soc15.h |
558 | +++ b/drivers/gpu/drm/amd/amdgpu/soc15.h |
559 | @@ -28,8 +28,8 @@ |
560 | #include "nbio_v7_0.h" |
561 | #include "nbio_v7_4.h" |
562 | |
563 | -#define SOC15_FLUSH_GPU_TLB_NUM_WREG 4 |
564 | -#define SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT 1 |
565 | +#define SOC15_FLUSH_GPU_TLB_NUM_WREG 6 |
566 | +#define SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT 3 |
567 | |
568 | extern const struct amd_ip_funcs soc15_common_ip_funcs; |
569 | |
570 | diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c |
571 | index f4cfa0caeba8..785322cd4c6c 100644 |
572 | --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c |
573 | +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c |
574 | @@ -342,7 +342,8 @@ bool dm_pp_get_clock_levels_by_type( |
575 | if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) { |
576 | if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle, |
577 | dc_to_pp_clock_type(clk_type), &pp_clks)) { |
578 | - /* Error in pplib. Provide default values. */ |
579 | + /* Error in pplib. Provide default values. */ |
580 | + get_default_clock_levels(clk_type, dc_clks); |
581 | return true; |
582 | } |
583 | } else if (adev->smu.funcs && adev->smu.funcs->get_clock_by_type) { |
584 | diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c |
585 | index 1212da12c414..b3ae1c41fc69 100644 |
586 | --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c |
587 | +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c |
588 | @@ -1103,6 +1103,25 @@ void dcn20_pipe_control_lock( |
589 | if (pipe->plane_state != NULL) |
590 | flip_immediate = pipe->plane_state->flip_immediate; |
591 | |
592 | + if (flip_immediate && lock) { |
593 | + const int TIMEOUT_FOR_FLIP_PENDING = 100000; |
594 | + int i; |
595 | + |
596 | + for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) { |
597 | + if (!pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->plane_res.hubp)) |
598 | + break; |
599 | + udelay(1); |
600 | + } |
601 | + |
602 | + if (pipe->bottom_pipe != NULL) { |
603 | + for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) { |
604 | + if (!pipe->bottom_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->bottom_pipe->plane_res.hubp)) |
605 | + break; |
606 | + udelay(1); |
607 | + } |
608 | + } |
609 | + } |
610 | + |
611 | /* In flip immediate and pipe splitting case, we need to use GSL |
612 | * for synchronization. Only do setup on locking and on flip type change. |
613 | */ |
614 | diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c |
615 | index 82add736e17d..86c17896b532 100644 |
616 | --- a/drivers/gpu/drm/drm_dp_mst_topology.c |
617 | +++ b/drivers/gpu/drm/drm_dp_mst_topology.c |
618 | @@ -2465,9 +2465,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) |
619 | drm_dp_mst_topology_put_port(port); |
620 | } |
621 | |
622 | - for (i = 0; i < mgr->max_payloads; i++) { |
623 | - if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) |
624 | + for (i = 0; i < mgr->max_payloads; /* do nothing */) { |
625 | + if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) { |
626 | + i++; |
627 | continue; |
628 | + } |
629 | |
630 | DRM_DEBUG_KMS("removing payload %d\n", i); |
631 | for (j = i; j < mgr->max_payloads - 1; j++) { |
632 | diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c |
633 | index 16ed44bfd734..07a038f21619 100644 |
634 | --- a/drivers/gpu/drm/i915/display/intel_fbc.c |
635 | +++ b/drivers/gpu/drm/i915/display/intel_fbc.c |
636 | @@ -1284,7 +1284,7 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv) |
637 | return 0; |
638 | |
639 | /* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */ |
640 | - if (IS_GEMINILAKE(dev_priv)) |
641 | + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
642 | return 0; |
643 | |
644 | if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) |
645 | diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c |
646 | index e753b1e706e2..fc29a3705354 100644 |
647 | --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c |
648 | +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c |
649 | @@ -1597,9 +1597,9 @@ static int cmd_handler_mi_op_2f(struct parser_exec_state *s) |
650 | if (!(cmd_val(s, 0) & (1 << 22))) |
651 | return ret; |
652 | |
653 | - /* check if QWORD */ |
654 | - if (DWORD_FIELD(0, 20, 19) == 1) |
655 | - valid_len += 8; |
656 | + /* check inline data */ |
657 | + if (cmd_val(s, 0) & BIT(18)) |
658 | + valid_len = CMD_LEN(9); |
659 | ret = gvt_check_valid_cmd_length(cmd_length(s), |
660 | valid_len); |
661 | if (ret) |
662 | diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c |
663 | index 9ab27aecfcf3..1bd6b6d15ffb 100644 |
664 | --- a/drivers/gpu/drm/meson/meson_venc_cvbs.c |
665 | +++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c |
666 | @@ -64,6 +64,25 @@ struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = { |
667 | }, |
668 | }; |
669 | |
670 | +static const struct meson_cvbs_mode * |
671 | +meson_cvbs_get_mode(const struct drm_display_mode *req_mode) |
672 | +{ |
673 | + int i; |
674 | + |
675 | + for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { |
676 | + struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; |
677 | + |
678 | + if (drm_mode_match(req_mode, &meson_mode->mode, |
679 | + DRM_MODE_MATCH_TIMINGS | |
680 | + DRM_MODE_MATCH_CLOCK | |
681 | + DRM_MODE_MATCH_FLAGS | |
682 | + DRM_MODE_MATCH_3D_FLAGS)) |
683 | + return meson_mode; |
684 | + } |
685 | + |
686 | + return NULL; |
687 | +} |
688 | + |
689 | /* Connector */ |
690 | |
691 | static void meson_cvbs_connector_destroy(struct drm_connector *connector) |
692 | @@ -136,14 +155,8 @@ static int meson_venc_cvbs_encoder_atomic_check(struct drm_encoder *encoder, |
693 | struct drm_crtc_state *crtc_state, |
694 | struct drm_connector_state *conn_state) |
695 | { |
696 | - int i; |
697 | - |
698 | - for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { |
699 | - struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; |
700 | - |
701 | - if (drm_mode_equal(&crtc_state->mode, &meson_mode->mode)) |
702 | - return 0; |
703 | - } |
704 | + if (meson_cvbs_get_mode(&crtc_state->mode)) |
705 | + return 0; |
706 | |
707 | return -EINVAL; |
708 | } |
709 | @@ -191,24 +204,17 @@ static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder, |
710 | struct drm_display_mode *mode, |
711 | struct drm_display_mode *adjusted_mode) |
712 | { |
713 | + const struct meson_cvbs_mode *meson_mode = meson_cvbs_get_mode(mode); |
714 | struct meson_venc_cvbs *meson_venc_cvbs = |
715 | encoder_to_meson_venc_cvbs(encoder); |
716 | struct meson_drm *priv = meson_venc_cvbs->priv; |
717 | - int i; |
718 | |
719 | - for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { |
720 | - struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; |
721 | + if (meson_mode) { |
722 | + meson_venci_cvbs_mode_set(priv, meson_mode->enci); |
723 | |
724 | - if (drm_mode_equal(mode, &meson_mode->mode)) { |
725 | - meson_venci_cvbs_mode_set(priv, |
726 | - meson_mode->enci); |
727 | - |
728 | - /* Setup 27MHz vclk2 for ENCI and VDAC */ |
729 | - meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, |
730 | - MESON_VCLK_CVBS, MESON_VCLK_CVBS, |
731 | - MESON_VCLK_CVBS, true); |
732 | - break; |
733 | - } |
734 | + /* Setup 27MHz vclk2 for ENCI and VDAC */ |
735 | + meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS, |
736 | + MESON_VCLK_CVBS, MESON_VCLK_CVBS, true); |
737 | } |
738 | } |
739 | |
740 | diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c |
741 | index afd9119b6cf1..c96c4393b124 100644 |
742 | --- a/drivers/gpu/drm/mgag200/mgag200_drv.c |
743 | +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c |
744 | @@ -30,7 +30,8 @@ module_param_named(modeset, mgag200_modeset, int, 0400); |
745 | static struct drm_driver driver; |
746 | |
747 | static const struct pci_device_id pciidlist[] = { |
748 | - { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A }, |
749 | + { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
750 | + G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD}, |
751 | { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B }, |
752 | { PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV }, |
753 | { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB }, |
754 | @@ -63,6 +64,35 @@ static const struct file_operations mgag200_driver_fops = { |
755 | DRM_VRAM_MM_FILE_OPERATIONS |
756 | }; |
757 | |
758 | +static bool mgag200_pin_bo_at_0(const struct mga_device *mdev) |
759 | +{ |
760 | + return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD; |
761 | +} |
762 | + |
763 | +int mgag200_driver_dumb_create(struct drm_file *file, |
764 | + struct drm_device *dev, |
765 | + struct drm_mode_create_dumb *args) |
766 | +{ |
767 | + struct mga_device *mdev = dev->dev_private; |
768 | + unsigned long pg_align; |
769 | + |
770 | + if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) |
771 | + return -EINVAL; |
772 | + |
773 | + pg_align = 0ul; |
774 | + |
775 | + /* |
776 | + * Aligning scanout buffers to the size of the video ram forces |
777 | + * placement at offset 0. Works around a bug where HW does not |
778 | + * respect 'startadd' field. |
779 | + */ |
780 | + if (mgag200_pin_bo_at_0(mdev)) |
781 | + pg_align = PFN_UP(mdev->mc.vram_size); |
782 | + |
783 | + return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev, |
784 | + pg_align, false, args); |
785 | +} |
786 | + |
787 | static struct drm_driver driver = { |
788 | .driver_features = DRIVER_GEM | DRIVER_MODESET, |
789 | .load = mgag200_driver_load, |
790 | @@ -74,7 +104,9 @@ static struct drm_driver driver = { |
791 | .major = DRIVER_MAJOR, |
792 | .minor = DRIVER_MINOR, |
793 | .patchlevel = DRIVER_PATCHLEVEL, |
794 | - DRM_GEM_VRAM_DRIVER |
795 | + .dumb_create = mgag200_driver_dumb_create, |
796 | + .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset, |
797 | + .gem_prime_mmap = drm_gem_prime_mmap, |
798 | }; |
799 | |
800 | static struct pci_driver mgag200_pci_driver = { |
801 | diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h |
802 | index 1c93f8dc08c7..7cc1a242df5f 100644 |
803 | --- a/drivers/gpu/drm/mgag200/mgag200_drv.h |
804 | +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h |
805 | @@ -159,6 +159,12 @@ enum mga_type { |
806 | G200_EW3, |
807 | }; |
808 | |
809 | +/* HW does not handle 'startadd' field correct. */ |
810 | +#define MGAG200_FLAG_HW_BUG_NO_STARTADD (1ul << 8) |
811 | + |
812 | +#define MGAG200_TYPE_MASK (0x000000ff) |
813 | +#define MGAG200_FLAG_MASK (0x00ffff00) |
814 | + |
815 | #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) |
816 | |
817 | struct mga_device { |
818 | @@ -188,6 +194,18 @@ struct mga_device { |
819 | u32 unique_rev_id; |
820 | }; |
821 | |
822 | +static inline enum mga_type |
823 | +mgag200_type_from_driver_data(kernel_ulong_t driver_data) |
824 | +{ |
825 | + return (enum mga_type)(driver_data & MGAG200_TYPE_MASK); |
826 | +} |
827 | + |
828 | +static inline unsigned long |
829 | +mgag200_flags_from_driver_data(kernel_ulong_t driver_data) |
830 | +{ |
831 | + return driver_data & MGAG200_FLAG_MASK; |
832 | +} |
833 | + |
834 | /* mgag200_mode.c */ |
835 | int mgag200_modeset_init(struct mga_device *mdev); |
836 | void mgag200_modeset_fini(struct mga_device *mdev); |
837 | diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c |
838 | index a9773334dedf..388212b2d63f 100644 |
839 | --- a/drivers/gpu/drm/mgag200/mgag200_main.c |
840 | +++ b/drivers/gpu/drm/mgag200/mgag200_main.c |
841 | @@ -94,7 +94,8 @@ static int mgag200_device_init(struct drm_device *dev, |
842 | struct mga_device *mdev = dev->dev_private; |
843 | int ret, option; |
844 | |
845 | - mdev->type = flags; |
846 | + mdev->flags = mgag200_flags_from_driver_data(flags); |
847 | + mdev->type = mgag200_type_from_driver_data(flags); |
848 | |
849 | /* Hardcode the number of CRTCs to 1 */ |
850 | mdev->num_crtc = 1; |
851 | diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h |
852 | index 43df86c38f58..24f7700768da 100644 |
853 | --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h |
854 | +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h |
855 | @@ -114,6 +114,7 @@ struct nv50_head_atom { |
856 | u8 nhsync:1; |
857 | u8 nvsync:1; |
858 | u8 depth:4; |
859 | + u8 bpc; |
860 | } or; |
861 | |
862 | /* Currently only used for MST */ |
863 | diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c |
864 | index b46be8a091e9..b5b1a34f896f 100644 |
865 | --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c |
866 | +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c |
867 | @@ -353,10 +353,20 @@ nv50_outp_atomic_check(struct drm_encoder *encoder, |
868 | struct drm_crtc_state *crtc_state, |
869 | struct drm_connector_state *conn_state) |
870 | { |
871 | - struct nouveau_connector *nv_connector = |
872 | - nouveau_connector(conn_state->connector); |
873 | - return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, |
874 | - nv_connector->native_mode); |
875 | + struct drm_connector *connector = conn_state->connector; |
876 | + struct nouveau_connector *nv_connector = nouveau_connector(connector); |
877 | + struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); |
878 | + int ret; |
879 | + |
880 | + ret = nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, |
881 | + nv_connector->native_mode); |
882 | + if (ret) |
883 | + return ret; |
884 | + |
885 | + if (crtc_state->mode_changed || crtc_state->connectors_changed) |
886 | + asyh->or.bpc = connector->display_info.bpc; |
887 | + |
888 | + return 0; |
889 | } |
890 | |
891 | /****************************************************************************** |
892 | @@ -770,32 +780,54 @@ nv50_msto_atomic_check(struct drm_encoder *encoder, |
893 | struct nv50_mstm *mstm = mstc->mstm; |
894 | struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); |
895 | int slots; |
896 | + int ret; |
897 | + |
898 | + ret = nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, |
899 | + mstc->native); |
900 | + if (ret) |
901 | + return ret; |
902 | + |
903 | + if (!crtc_state->mode_changed && !crtc_state->connectors_changed) |
904 | + return 0; |
905 | + |
906 | + /* |
907 | + * When restoring duplicated states, we need to make sure that the bw |
908 | + * remains the same and avoid recalculating it, as the connector's bpc |
909 | + * may have changed after the state was duplicated |
910 | + */ |
911 | + if (!state->duplicated) { |
912 | + const int clock = crtc_state->adjusted_mode.clock; |
913 | |
914 | - if (crtc_state->mode_changed || crtc_state->connectors_changed) { |
915 | /* |
916 | - * When restoring duplicated states, we need to make sure that |
917 | - * the bw remains the same and avoid recalculating it, as the |
918 | - * connector's bpc may have changed after the state was |
919 | - * duplicated |
920 | + * XXX: Since we don't use HDR in userspace quite yet, limit |
921 | + * the bpc to 8 to save bandwidth on the topology. In the |
922 | + * future, we'll want to properly fix this by dynamically |
923 | + * selecting the highest possible bpc that would fit in the |
924 | + * topology |
925 | */ |
926 | - if (!state->duplicated) { |
927 | - const int bpp = connector->display_info.bpc * 3; |
928 | - const int clock = crtc_state->adjusted_mode.clock; |
929 | + asyh->or.bpc = min(connector->display_info.bpc, 8U); |
930 | + asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, asyh->or.bpc * 3); |
931 | + } |
932 | |
933 | - asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, bpp); |
934 | - } |
935 | + slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, mstc->port, |
936 | + asyh->dp.pbn); |
937 | + if (slots < 0) |
938 | + return slots; |
939 | |
940 | - slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, |
941 | - mstc->port, |
942 | - asyh->dp.pbn); |
943 | - if (slots < 0) |
944 | - return slots; |
945 | + asyh->dp.tu = slots; |
946 | |
947 | - asyh->dp.tu = slots; |
948 | - } |
949 | + return 0; |
950 | +} |
951 | |
952 | - return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, |
953 | - mstc->native); |
954 | +static u8 |
955 | +nv50_dp_bpc_to_depth(unsigned int bpc) |
956 | +{ |
957 | + switch (bpc) { |
958 | + case 6: return 0x2; |
959 | + case 8: return 0x5; |
960 | + case 10: /* fall-through */ |
961 | + default: return 0x6; |
962 | + } |
963 | } |
964 | |
965 | static void |
966 | @@ -808,7 +840,7 @@ nv50_msto_enable(struct drm_encoder *encoder) |
967 | struct nv50_mstm *mstm = NULL; |
968 | struct drm_connector *connector; |
969 | struct drm_connector_list_iter conn_iter; |
970 | - u8 proto, depth; |
971 | + u8 proto; |
972 | bool r; |
973 | |
974 | drm_connector_list_iter_begin(encoder->dev, &conn_iter); |
975 | @@ -837,14 +869,8 @@ nv50_msto_enable(struct drm_encoder *encoder) |
976 | else |
977 | proto = 0x9; |
978 | |
979 | - switch (mstc->connector.display_info.bpc) { |
980 | - case 6: depth = 0x2; break; |
981 | - case 8: depth = 0x5; break; |
982 | - case 10: |
983 | - default: depth = 0x6; break; |
984 | - } |
985 | - |
986 | - mstm->outp->update(mstm->outp, head->base.index, armh, proto, depth); |
987 | + mstm->outp->update(mstm->outp, head->base.index, armh, proto, |
988 | + nv50_dp_bpc_to_depth(armh->or.bpc)); |
989 | |
990 | msto->head = head; |
991 | msto->mstc = mstc; |
992 | @@ -1498,20 +1524,14 @@ nv50_sor_enable(struct drm_encoder *encoder) |
993 | lvds.lvds.script |= 0x0200; |
994 | } |
995 | |
996 | - if (nv_connector->base.display_info.bpc == 8) |
997 | + if (asyh->or.bpc == 8) |
998 | lvds.lvds.script |= 0x0200; |
999 | } |
1000 | |
1001 | nvif_mthd(&disp->disp->object, 0, &lvds, sizeof(lvds)); |
1002 | break; |
1003 | case DCB_OUTPUT_DP: |
1004 | - if (nv_connector->base.display_info.bpc == 6) |
1005 | - depth = 0x2; |
1006 | - else |
1007 | - if (nv_connector->base.display_info.bpc == 8) |
1008 | - depth = 0x5; |
1009 | - else |
1010 | - depth = 0x6; |
1011 | + depth = nv50_dp_bpc_to_depth(asyh->or.bpc); |
1012 | |
1013 | if (nv_encoder->link & 1) |
1014 | proto = 0x8; |
1015 | @@ -1662,7 +1682,7 @@ nv50_pior_enable(struct drm_encoder *encoder) |
1016 | nv50_outp_acquire(nv_encoder); |
1017 | |
1018 | nv_connector = nouveau_encoder_connector_get(nv_encoder); |
1019 | - switch (nv_connector->base.display_info.bpc) { |
1020 | + switch (asyh->or.bpc) { |
1021 | case 10: asyh->or.depth = 0x6; break; |
1022 | case 8: asyh->or.depth = 0x5; break; |
1023 | case 6: asyh->or.depth = 0x2; break; |
1024 | diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c |
1025 | index 71c23bf1fe25..c9692df2b76c 100644 |
1026 | --- a/drivers/gpu/drm/nouveau/dispnv50/head.c |
1027 | +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c |
1028 | @@ -81,18 +81,17 @@ nv50_head_atomic_check_dither(struct nv50_head_atom *armh, |
1029 | struct nv50_head_atom *asyh, |
1030 | struct nouveau_conn_atom *asyc) |
1031 | { |
1032 | - struct drm_connector *connector = asyc->state.connector; |
1033 | u32 mode = 0x00; |
1034 | |
1035 | if (asyc->dither.mode == DITHERING_MODE_AUTO) { |
1036 | - if (asyh->base.depth > connector->display_info.bpc * 3) |
1037 | + if (asyh->base.depth > asyh->or.bpc * 3) |
1038 | mode = DITHERING_MODE_DYNAMIC2X2; |
1039 | } else { |
1040 | mode = asyc->dither.mode; |
1041 | } |
1042 | |
1043 | if (asyc->dither.depth == DITHERING_DEPTH_AUTO) { |
1044 | - if (connector->display_info.bpc >= 8) |
1045 | + if (asyh->or.bpc >= 8) |
1046 | mode |= DITHERING_DEPTH_8BPC; |
1047 | } else { |
1048 | mode |= asyc->dither.depth; |
1049 | diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c |
1050 | index bdf91b75328e..1c67ac434e10 100644 |
1051 | --- a/drivers/gpu/drm/panfrost/panfrost_drv.c |
1052 | +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c |
1053 | @@ -303,14 +303,17 @@ static int panfrost_ioctl_mmap_bo(struct drm_device *dev, void *data, |
1054 | } |
1055 | |
1056 | /* Don't allow mmapping of heap objects as pages are not pinned. */ |
1057 | - if (to_panfrost_bo(gem_obj)->is_heap) |
1058 | - return -EINVAL; |
1059 | + if (to_panfrost_bo(gem_obj)->is_heap) { |
1060 | + ret = -EINVAL; |
1061 | + goto out; |
1062 | + } |
1063 | |
1064 | ret = drm_gem_create_mmap_offset(gem_obj); |
1065 | if (ret == 0) |
1066 | args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); |
1067 | - drm_gem_object_put_unlocked(gem_obj); |
1068 | |
1069 | +out: |
1070 | + drm_gem_object_put_unlocked(gem_obj); |
1071 | return ret; |
1072 | } |
1073 | |
1074 | @@ -347,20 +350,19 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, |
1075 | return -ENOENT; |
1076 | } |
1077 | |
1078 | + mutex_lock(&pfdev->shrinker_lock); |
1079 | args->retained = drm_gem_shmem_madvise(gem_obj, args->madv); |
1080 | |
1081 | if (args->retained) { |
1082 | struct panfrost_gem_object *bo = to_panfrost_bo(gem_obj); |
1083 | |
1084 | - mutex_lock(&pfdev->shrinker_lock); |
1085 | - |
1086 | if (args->madv == PANFROST_MADV_DONTNEED) |
1087 | - list_add_tail(&bo->base.madv_list, &pfdev->shrinker_list); |
1088 | + list_add_tail(&bo->base.madv_list, |
1089 | + &pfdev->shrinker_list); |
1090 | else if (args->madv == PANFROST_MADV_WILLNEED) |
1091 | list_del_init(&bo->base.madv_list); |
1092 | - |
1093 | - mutex_unlock(&pfdev->shrinker_lock); |
1094 | } |
1095 | + mutex_unlock(&pfdev->shrinker_lock); |
1096 | |
1097 | drm_gem_object_put_unlocked(gem_obj); |
1098 | return 0; |
1099 | diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c |
1100 | index bc3ff22e5e85..92a95210a899 100644 |
1101 | --- a/drivers/gpu/drm/panfrost/panfrost_gem.c |
1102 | +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c |
1103 | @@ -19,6 +19,16 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) |
1104 | struct panfrost_gem_object *bo = to_panfrost_bo(obj); |
1105 | struct panfrost_device *pfdev = obj->dev->dev_private; |
1106 | |
1107 | + /* |
1108 | + * Make sure the BO is no longer inserted in the shrinker list before |
1109 | + * taking care of the destruction itself. If we don't do that we have a |
1110 | + * race condition between this function and what's done in |
1111 | + * panfrost_gem_shrinker_scan(). |
1112 | + */ |
1113 | + mutex_lock(&pfdev->shrinker_lock); |
1114 | + list_del_init(&bo->base.madv_list); |
1115 | + mutex_unlock(&pfdev->shrinker_lock); |
1116 | + |
1117 | if (bo->sgts) { |
1118 | int i; |
1119 | int n_sgt = bo->base.base.size / SZ_2M; |
1120 | @@ -33,11 +43,6 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) |
1121 | kfree(bo->sgts); |
1122 | } |
1123 | |
1124 | - mutex_lock(&pfdev->shrinker_lock); |
1125 | - if (!list_empty(&bo->base.madv_list)) |
1126 | - list_del(&bo->base.madv_list); |
1127 | - mutex_unlock(&pfdev->shrinker_lock); |
1128 | - |
1129 | drm_gem_shmem_free_object(obj); |
1130 | } |
1131 | |
1132 | diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c |
1133 | index 7089dfc8c2a9..110fb38004b1 100644 |
1134 | --- a/drivers/gpu/drm/radeon/r100.c |
1135 | +++ b/drivers/gpu/drm/radeon/r100.c |
1136 | @@ -1826,8 +1826,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p, |
1137 | track->textures[i].use_pitch = 1; |
1138 | } else { |
1139 | track->textures[i].use_pitch = 0; |
1140 | - track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); |
1141 | - track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); |
1142 | + track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT); |
1143 | + track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT); |
1144 | } |
1145 | if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) |
1146 | track->textures[i].tex_coord_type = 2; |
1147 | diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c |
1148 | index 840401413c58..f5f2ffea5ab2 100644 |
1149 | --- a/drivers/gpu/drm/radeon/r200.c |
1150 | +++ b/drivers/gpu/drm/radeon/r200.c |
1151 | @@ -476,8 +476,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, |
1152 | track->textures[i].use_pitch = 1; |
1153 | } else { |
1154 | track->textures[i].use_pitch = 0; |
1155 | - track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); |
1156 | - track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); |
1157 | + track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT); |
1158 | + track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT); |
1159 | } |
1160 | if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE) |
1161 | track->textures[i].lookup_disable = true; |
1162 | diff --git a/drivers/md/dm-clone-metadata.c b/drivers/md/dm-clone-metadata.c |
1163 | index 6bc8c1d1c351..54e4fdd607e1 100644 |
1164 | --- a/drivers/md/dm-clone-metadata.c |
1165 | +++ b/drivers/md/dm-clone-metadata.c |
1166 | @@ -67,23 +67,34 @@ struct superblock_disk { |
1167 | * To save constantly doing look ups on disk we keep an in core copy of the |
1168 | * on-disk bitmap, the region_map. |
1169 | * |
1170 | - * To further reduce metadata I/O overhead we use a second bitmap, the dmap |
1171 | - * (dirty bitmap), which tracks the dirty words, i.e. longs, of the region_map. |
1172 | + * In order to track which regions are hydrated during a metadata transaction, |
1173 | + * we use a second set of bitmaps, the dmap (dirty bitmap), which includes two |
1174 | + * bitmaps, namely dirty_regions and dirty_words. The dirty_regions bitmap |
1175 | + * tracks the regions that got hydrated during the current metadata |
1176 | + * transaction. The dirty_words bitmap tracks the dirty words, i.e. longs, of |
1177 | + * the dirty_regions bitmap. |
1178 | + * |
1179 | + * This allows us to precisely track the regions that were hydrated during the |
1180 | + * current metadata transaction and update the metadata accordingly, when we |
1181 | + * commit the current transaction. This is important because dm-clone should |
1182 | + * only commit the metadata of regions that were properly flushed to the |
1183 | + * destination device beforehand. Otherwise, in case of a crash, we could end |
1184 | + * up with a corrupted dm-clone device. |
1185 | * |
1186 | * When a region finishes hydrating dm-clone calls |
1187 | * dm_clone_set_region_hydrated(), or for discard requests |
1188 | * dm_clone_cond_set_range(), which sets the corresponding bits in region_map |
1189 | * and dmap. |
1190 | * |
1191 | - * During a metadata commit we scan the dmap for dirty region_map words (longs) |
1192 | - * and update accordingly the on-disk metadata. Thus, we don't have to flush to |
1193 | - * disk the whole region_map. We can just flush the dirty region_map words. |
1194 | + * During a metadata commit we scan dmap->dirty_words and dmap->dirty_regions |
1195 | + * and update the on-disk metadata accordingly. Thus, we don't have to flush to |
1196 | + * disk the whole region_map. We can just flush the dirty region_map bits. |
1197 | * |
1198 | - * We use a dirty bitmap, which is smaller than the original region_map, to |
1199 | - * reduce the amount of memory accesses during a metadata commit. As dm-bitset |
1200 | - * accesses the on-disk bitmap in 64-bit word granularity, there is no |
1201 | - * significant benefit in tracking the dirty region_map bits with a smaller |
1202 | - * granularity. |
1203 | + * We use the helper dmap->dirty_words bitmap, which is smaller than the |
1204 | + * original region_map, to reduce the amount of memory accesses during a |
1205 | + * metadata commit. Moreover, as dm-bitset also accesses the on-disk bitmap in |
1206 | + * 64-bit word granularity, the dirty_words bitmap helps us avoid useless disk |
1207 | + * accesses. |
1208 | * |
1209 | * We could update directly the on-disk bitmap, when dm-clone calls either |
1210 | * dm_clone_set_region_hydrated() or dm_clone_cond_set_range(), buts this |
1211 | @@ -92,12 +103,13 @@ struct superblock_disk { |
1212 | * e.g., in a hooked overwrite bio's completion routine, and further reduce the |
1213 | * I/O completion latency. |
1214 | * |
1215 | - * We maintain two dirty bitmaps. During a metadata commit we atomically swap |
1216 | - * the currently used dmap with the unused one. This allows the metadata update |
1217 | - * functions to run concurrently with an ongoing commit. |
1218 | + * We maintain two dirty bitmap sets. During a metadata commit we atomically |
1219 | + * swap the currently used dmap with the unused one. This allows the metadata |
1220 | + * update functions to run concurrently with an ongoing commit. |
1221 | */ |
1222 | struct dirty_map { |
1223 | unsigned long *dirty_words; |
1224 | + unsigned long *dirty_regions; |
1225 | unsigned int changed; |
1226 | }; |
1227 | |
1228 | @@ -115,6 +127,9 @@ struct dm_clone_metadata { |
1229 | struct dirty_map dmap[2]; |
1230 | struct dirty_map *current_dmap; |
1231 | |
1232 | + /* Protected by lock */ |
1233 | + struct dirty_map *committing_dmap; |
1234 | + |
1235 | /* |
1236 | * In core copy of the on-disk bitmap to save constantly doing look ups |
1237 | * on disk. |
1238 | @@ -461,34 +476,53 @@ static size_t bitmap_size(unsigned long nr_bits) |
1239 | return BITS_TO_LONGS(nr_bits) * sizeof(long); |
1240 | } |
1241 | |
1242 | -static int dirty_map_init(struct dm_clone_metadata *cmd) |
1243 | +static int __dirty_map_init(struct dirty_map *dmap, unsigned long nr_words, |
1244 | + unsigned long nr_regions) |
1245 | { |
1246 | - cmd->dmap[0].changed = 0; |
1247 | - cmd->dmap[0].dirty_words = kvzalloc(bitmap_size(cmd->nr_words), GFP_KERNEL); |
1248 | + dmap->changed = 0; |
1249 | |
1250 | - if (!cmd->dmap[0].dirty_words) { |
1251 | - DMERR("Failed to allocate dirty bitmap"); |
1252 | + dmap->dirty_words = kvzalloc(bitmap_size(nr_words), GFP_KERNEL); |
1253 | + if (!dmap->dirty_words) |
1254 | + return -ENOMEM; |
1255 | + |
1256 | + dmap->dirty_regions = kvzalloc(bitmap_size(nr_regions), GFP_KERNEL); |
1257 | + if (!dmap->dirty_regions) { |
1258 | + kvfree(dmap->dirty_words); |
1259 | return -ENOMEM; |
1260 | } |
1261 | |
1262 | - cmd->dmap[1].changed = 0; |
1263 | - cmd->dmap[1].dirty_words = kvzalloc(bitmap_size(cmd->nr_words), GFP_KERNEL); |
1264 | + return 0; |
1265 | +} |
1266 | + |
1267 | +static void __dirty_map_exit(struct dirty_map *dmap) |
1268 | +{ |
1269 | + kvfree(dmap->dirty_words); |
1270 | + kvfree(dmap->dirty_regions); |
1271 | +} |
1272 | + |
1273 | +static int dirty_map_init(struct dm_clone_metadata *cmd) |
1274 | +{ |
1275 | + if (__dirty_map_init(&cmd->dmap[0], cmd->nr_words, cmd->nr_regions)) { |
1276 | + DMERR("Failed to allocate dirty bitmap"); |
1277 | + return -ENOMEM; |
1278 | + } |
1279 | |
1280 | - if (!cmd->dmap[1].dirty_words) { |
1281 | + if (__dirty_map_init(&cmd->dmap[1], cmd->nr_words, cmd->nr_regions)) { |
1282 | DMERR("Failed to allocate dirty bitmap"); |
1283 | - kvfree(cmd->dmap[0].dirty_words); |
1284 | + __dirty_map_exit(&cmd->dmap[0]); |
1285 | return -ENOMEM; |
1286 | } |
1287 | |
1288 | cmd->current_dmap = &cmd->dmap[0]; |
1289 | + cmd->committing_dmap = NULL; |
1290 | |
1291 | return 0; |
1292 | } |
1293 | |
1294 | static void dirty_map_exit(struct dm_clone_metadata *cmd) |
1295 | { |
1296 | - kvfree(cmd->dmap[0].dirty_words); |
1297 | - kvfree(cmd->dmap[1].dirty_words); |
1298 | + __dirty_map_exit(&cmd->dmap[0]); |
1299 | + __dirty_map_exit(&cmd->dmap[1]); |
1300 | } |
1301 | |
1302 | static int __load_bitset_in_core(struct dm_clone_metadata *cmd) |
1303 | @@ -633,21 +667,23 @@ unsigned long dm_clone_find_next_unhydrated_region(struct dm_clone_metadata *cmd |
1304 | return find_next_zero_bit(cmd->region_map, cmd->nr_regions, start); |
1305 | } |
1306 | |
1307 | -static int __update_metadata_word(struct dm_clone_metadata *cmd, unsigned long word) |
1308 | +static int __update_metadata_word(struct dm_clone_metadata *cmd, |
1309 | + unsigned long *dirty_regions, |
1310 | + unsigned long word) |
1311 | { |
1312 | int r; |
1313 | unsigned long index = word * BITS_PER_LONG; |
1314 | unsigned long max_index = min(cmd->nr_regions, (word + 1) * BITS_PER_LONG); |
1315 | |
1316 | while (index < max_index) { |
1317 | - if (test_bit(index, cmd->region_map)) { |
1318 | + if (test_bit(index, dirty_regions)) { |
1319 | r = dm_bitset_set_bit(&cmd->bitset_info, cmd->bitset_root, |
1320 | index, &cmd->bitset_root); |
1321 | - |
1322 | if (r) { |
1323 | DMERR("dm_bitset_set_bit failed"); |
1324 | return r; |
1325 | } |
1326 | + __clear_bit(index, dirty_regions); |
1327 | } |
1328 | index++; |
1329 | } |
1330 | @@ -721,7 +757,7 @@ static int __flush_dmap(struct dm_clone_metadata *cmd, struct dirty_map *dmap) |
1331 | if (word == cmd->nr_words) |
1332 | break; |
1333 | |
1334 | - r = __update_metadata_word(cmd, word); |
1335 | + r = __update_metadata_word(cmd, dmap->dirty_regions, word); |
1336 | |
1337 | if (r) |
1338 | return r; |
1339 | @@ -743,16 +779,18 @@ static int __flush_dmap(struct dm_clone_metadata *cmd, struct dirty_map *dmap) |
1340 | return 0; |
1341 | } |
1342 | |
1343 | -int dm_clone_metadata_commit(struct dm_clone_metadata *cmd) |
1344 | +int dm_clone_metadata_pre_commit(struct dm_clone_metadata *cmd) |
1345 | { |
1346 | - int r = -EPERM; |
1347 | + int r = 0; |
1348 | unsigned long flags; |
1349 | struct dirty_map *dmap, *next_dmap; |
1350 | |
1351 | down_write(&cmd->lock); |
1352 | |
1353 | - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) |
1354 | + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { |
1355 | + r = -EPERM; |
1356 | goto out; |
1357 | + } |
1358 | |
1359 | /* Get current dirty bitmap */ |
1360 | dmap = cmd->current_dmap; |
1361 | @@ -764,7 +802,7 @@ int dm_clone_metadata_commit(struct dm_clone_metadata *cmd) |
1362 | * The last commit failed, so we don't have a clean dirty-bitmap to |
1363 | * use. |
1364 | */ |
1365 | - if (WARN_ON(next_dmap->changed)) { |
1366 | + if (WARN_ON(next_dmap->changed || cmd->committing_dmap)) { |
1367 | r = -EINVAL; |
1368 | goto out; |
1369 | } |
1370 | @@ -774,11 +812,33 @@ int dm_clone_metadata_commit(struct dm_clone_metadata *cmd) |
1371 | cmd->current_dmap = next_dmap; |
1372 | spin_unlock_irqrestore(&cmd->bitmap_lock, flags); |
1373 | |
1374 | - /* |
1375 | - * No one is accessing the old dirty bitmap anymore, so we can flush |
1376 | - * it. |
1377 | - */ |
1378 | - r = __flush_dmap(cmd, dmap); |
1379 | + /* Set old dirty bitmap as currently committing */ |
1380 | + cmd->committing_dmap = dmap; |
1381 | +out: |
1382 | + up_write(&cmd->lock); |
1383 | + |
1384 | + return r; |
1385 | +} |
1386 | + |
1387 | +int dm_clone_metadata_commit(struct dm_clone_metadata *cmd) |
1388 | +{ |
1389 | + int r = -EPERM; |
1390 | + |
1391 | + down_write(&cmd->lock); |
1392 | + |
1393 | + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) |
1394 | + goto out; |
1395 | + |
1396 | + if (WARN_ON(!cmd->committing_dmap)) { |
1397 | + r = -EINVAL; |
1398 | + goto out; |
1399 | + } |
1400 | + |
1401 | + r = __flush_dmap(cmd, cmd->committing_dmap); |
1402 | + if (!r) { |
1403 | + /* Clear committing dmap */ |
1404 | + cmd->committing_dmap = NULL; |
1405 | + } |
1406 | out: |
1407 | up_write(&cmd->lock); |
1408 | |
1409 | @@ -803,6 +863,7 @@ int dm_clone_set_region_hydrated(struct dm_clone_metadata *cmd, unsigned long re |
1410 | dmap = cmd->current_dmap; |
1411 | |
1412 | __set_bit(word, dmap->dirty_words); |
1413 | + __set_bit(region_nr, dmap->dirty_regions); |
1414 | __set_bit(region_nr, cmd->region_map); |
1415 | dmap->changed = 1; |
1416 | |
1417 | @@ -831,6 +892,7 @@ int dm_clone_cond_set_range(struct dm_clone_metadata *cmd, unsigned long start, |
1418 | if (!test_bit(region_nr, cmd->region_map)) { |
1419 | word = region_nr / BITS_PER_LONG; |
1420 | __set_bit(word, dmap->dirty_words); |
1421 | + __set_bit(region_nr, dmap->dirty_regions); |
1422 | __set_bit(region_nr, cmd->region_map); |
1423 | dmap->changed = 1; |
1424 | } |
1425 | diff --git a/drivers/md/dm-clone-metadata.h b/drivers/md/dm-clone-metadata.h |
1426 | index 434bff08508b..c7848c49aef8 100644 |
1427 | --- a/drivers/md/dm-clone-metadata.h |
1428 | +++ b/drivers/md/dm-clone-metadata.h |
1429 | @@ -73,7 +73,23 @@ void dm_clone_metadata_close(struct dm_clone_metadata *cmd); |
1430 | |
1431 | /* |
1432 | * Commit dm-clone metadata to disk. |
1433 | + * |
1434 | + * We use a two phase commit: |
1435 | + * |
1436 | + * 1. dm_clone_metadata_pre_commit(): Prepare the current transaction for |
1437 | + * committing. After this is called, all subsequent metadata updates, done |
1438 | + * through either dm_clone_set_region_hydrated() or |
1439 | + * dm_clone_cond_set_range(), will be part of the **next** transaction. |
1440 | + * |
1441 | + * 2. dm_clone_metadata_commit(): Actually commit the current transaction to |
1442 | + * disk and start a new transaction. |
1443 | + * |
1444 | + * This allows dm-clone to flush the destination device after step (1) to |
1445 | + * ensure that all freshly hydrated regions, for which we are updating the |
1446 | + * metadata, are properly written to non-volatile storage and won't be lost in |
1447 | + * case of a crash. |
1448 | */ |
1449 | +int dm_clone_metadata_pre_commit(struct dm_clone_metadata *cmd); |
1450 | int dm_clone_metadata_commit(struct dm_clone_metadata *cmd); |
1451 | |
1452 | /* |
1453 | @@ -110,6 +126,7 @@ int dm_clone_metadata_abort(struct dm_clone_metadata *cmd); |
1454 | * Switches metadata to a read only mode. Once read-only mode has been entered |
1455 | * the following functions will return -EPERM: |
1456 | * |
1457 | + * dm_clone_metadata_pre_commit() |
1458 | * dm_clone_metadata_commit() |
1459 | * dm_clone_set_region_hydrated() |
1460 | * dm_clone_cond_set_range() |
1461 | diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c |
1462 | index 4ca8f1977222..e6e5d24a79f5 100644 |
1463 | --- a/drivers/md/dm-clone-target.c |
1464 | +++ b/drivers/md/dm-clone-target.c |
1465 | @@ -86,6 +86,12 @@ struct clone { |
1466 | |
1467 | struct dm_clone_metadata *cmd; |
1468 | |
1469 | + /* |
1470 | + * bio used to flush the destination device, before committing the |
1471 | + * metadata. |
1472 | + */ |
1473 | + struct bio flush_bio; |
1474 | + |
1475 | /* Region hydration hash table */ |
1476 | struct hash_table_bucket *ht; |
1477 | |
1478 | @@ -1106,10 +1112,13 @@ static bool need_commit_due_to_time(struct clone *clone) |
1479 | /* |
1480 | * A non-zero return indicates read-only or fail mode. |
1481 | */ |
1482 | -static int commit_metadata(struct clone *clone) |
1483 | +static int commit_metadata(struct clone *clone, bool *dest_dev_flushed) |
1484 | { |
1485 | int r = 0; |
1486 | |
1487 | + if (dest_dev_flushed) |
1488 | + *dest_dev_flushed = false; |
1489 | + |
1490 | mutex_lock(&clone->commit_lock); |
1491 | |
1492 | if (!dm_clone_changed_this_transaction(clone->cmd)) |
1493 | @@ -1120,8 +1129,26 @@ static int commit_metadata(struct clone *clone) |
1494 | goto out; |
1495 | } |
1496 | |
1497 | - r = dm_clone_metadata_commit(clone->cmd); |
1498 | + r = dm_clone_metadata_pre_commit(clone->cmd); |
1499 | + if (unlikely(r)) { |
1500 | + __metadata_operation_failed(clone, "dm_clone_metadata_pre_commit", r); |
1501 | + goto out; |
1502 | + } |
1503 | |
1504 | + bio_reset(&clone->flush_bio); |
1505 | + bio_set_dev(&clone->flush_bio, clone->dest_dev->bdev); |
1506 | + clone->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; |
1507 | + |
1508 | + r = submit_bio_wait(&clone->flush_bio); |
1509 | + if (unlikely(r)) { |
1510 | + __metadata_operation_failed(clone, "flush destination device", r); |
1511 | + goto out; |
1512 | + } |
1513 | + |
1514 | + if (dest_dev_flushed) |
1515 | + *dest_dev_flushed = true; |
1516 | + |
1517 | + r = dm_clone_metadata_commit(clone->cmd); |
1518 | if (unlikely(r)) { |
1519 | __metadata_operation_failed(clone, "dm_clone_metadata_commit", r); |
1520 | goto out; |
1521 | @@ -1194,6 +1221,7 @@ static void process_deferred_flush_bios(struct clone *clone) |
1522 | { |
1523 | struct bio *bio; |
1524 | unsigned long flags; |
1525 | + bool dest_dev_flushed; |
1526 | struct bio_list bios = BIO_EMPTY_LIST; |
1527 | struct bio_list bio_completions = BIO_EMPTY_LIST; |
1528 | |
1529 | @@ -1213,7 +1241,7 @@ static void process_deferred_flush_bios(struct clone *clone) |
1530 | !(dm_clone_changed_this_transaction(clone->cmd) && need_commit_due_to_time(clone))) |
1531 | return; |
1532 | |
1533 | - if (commit_metadata(clone)) { |
1534 | + if (commit_metadata(clone, &dest_dev_flushed)) { |
1535 | bio_list_merge(&bios, &bio_completions); |
1536 | |
1537 | while ((bio = bio_list_pop(&bios))) |
1538 | @@ -1227,8 +1255,17 @@ static void process_deferred_flush_bios(struct clone *clone) |
1539 | while ((bio = bio_list_pop(&bio_completions))) |
1540 | bio_endio(bio); |
1541 | |
1542 | - while ((bio = bio_list_pop(&bios))) |
1543 | - generic_make_request(bio); |
1544 | + while ((bio = bio_list_pop(&bios))) { |
1545 | + if ((bio->bi_opf & REQ_PREFLUSH) && dest_dev_flushed) { |
1546 | + /* We just flushed the destination device as part of |
1547 | + * the metadata commit, so there is no reason to send |
1548 | + * another flush. |
1549 | + */ |
1550 | + bio_endio(bio); |
1551 | + } else { |
1552 | + generic_make_request(bio); |
1553 | + } |
1554 | + } |
1555 | } |
1556 | |
1557 | static void do_worker(struct work_struct *work) |
1558 | @@ -1400,7 +1437,7 @@ static void clone_status(struct dm_target *ti, status_type_t type, |
1559 | |
1560 | /* Commit to ensure statistics aren't out-of-date */ |
1561 | if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti)) |
1562 | - (void) commit_metadata(clone); |
1563 | + (void) commit_metadata(clone, NULL); |
1564 | |
1565 | r = dm_clone_get_free_metadata_block_count(clone->cmd, &nr_free_metadata_blocks); |
1566 | |
1567 | @@ -1834,6 +1871,7 @@ static int clone_ctr(struct dm_target *ti, unsigned int argc, char **argv) |
1568 | bio_list_init(&clone->deferred_flush_completions); |
1569 | clone->hydration_offset = 0; |
1570 | atomic_set(&clone->hydrations_in_flight, 0); |
1571 | + bio_init(&clone->flush_bio, NULL, 0); |
1572 | |
1573 | clone->wq = alloc_workqueue("dm-" DM_MSG_PREFIX, WQ_MEM_RECLAIM, 0); |
1574 | if (!clone->wq) { |
1575 | @@ -1907,6 +1945,7 @@ static void clone_dtr(struct dm_target *ti) |
1576 | struct clone *clone = ti->private; |
1577 | |
1578 | mutex_destroy(&clone->commit_lock); |
1579 | + bio_uninit(&clone->flush_bio); |
1580 | |
1581 | for (i = 0; i < clone->nr_ctr_args; i++) |
1582 | kfree(clone->ctr_args[i]); |
1583 | @@ -1961,7 +2000,7 @@ static void clone_postsuspend(struct dm_target *ti) |
1584 | wait_event(clone->hydration_stopped, !atomic_read(&clone->hydrations_in_flight)); |
1585 | flush_workqueue(clone->wq); |
1586 | |
1587 | - (void) commit_metadata(clone); |
1588 | + (void) commit_metadata(clone, NULL); |
1589 | } |
1590 | |
1591 | static void clone_resume(struct dm_target *ti) |
1592 | diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c |
1593 | index dbcc1e41cd57..e0c32793c248 100644 |
1594 | --- a/drivers/md/dm-mpath.c |
1595 | +++ b/drivers/md/dm-mpath.c |
1596 | @@ -599,45 +599,10 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) |
1597 | return pgpath; |
1598 | } |
1599 | |
1600 | -static struct pgpath *__map_bio_fast(struct multipath *m, struct bio *bio) |
1601 | -{ |
1602 | - struct pgpath *pgpath; |
1603 | - unsigned long flags; |
1604 | - |
1605 | - /* Do we need to select a new pgpath? */ |
1606 | - /* |
1607 | - * FIXME: currently only switching path if no path (due to failure, etc) |
1608 | - * - which negates the point of using a path selector |
1609 | - */ |
1610 | - pgpath = READ_ONCE(m->current_pgpath); |
1611 | - if (!pgpath) |
1612 | - pgpath = choose_pgpath(m, bio->bi_iter.bi_size); |
1613 | - |
1614 | - if (!pgpath) { |
1615 | - if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { |
1616 | - /* Queue for the daemon to resubmit */ |
1617 | - spin_lock_irqsave(&m->lock, flags); |
1618 | - bio_list_add(&m->queued_bios, bio); |
1619 | - spin_unlock_irqrestore(&m->lock, flags); |
1620 | - queue_work(kmultipathd, &m->process_queued_bios); |
1621 | - |
1622 | - return ERR_PTR(-EAGAIN); |
1623 | - } |
1624 | - return NULL; |
1625 | - } |
1626 | - |
1627 | - return pgpath; |
1628 | -} |
1629 | - |
1630 | static int __multipath_map_bio(struct multipath *m, struct bio *bio, |
1631 | struct dm_mpath_io *mpio) |
1632 | { |
1633 | - struct pgpath *pgpath; |
1634 | - |
1635 | - if (!m->hw_handler_name) |
1636 | - pgpath = __map_bio_fast(m, bio); |
1637 | - else |
1638 | - pgpath = __map_bio(m, bio); |
1639 | + struct pgpath *pgpath = __map_bio(m, bio); |
1640 | |
1641 | if (IS_ERR(pgpath)) |
1642 | return DM_MAPIO_SUBMITTED; |
1643 | diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c |
1644 | index 4c68a7b93d5e..b88d6d701f5b 100644 |
1645 | --- a/drivers/md/dm-thin-metadata.c |
1646 | +++ b/drivers/md/dm-thin-metadata.c |
1647 | @@ -188,6 +188,15 @@ struct dm_pool_metadata { |
1648 | unsigned long flags; |
1649 | sector_t data_block_size; |
1650 | |
1651 | + /* |
1652 | + * Pre-commit callback. |
1653 | + * |
1654 | + * This allows the thin provisioning target to run a callback before |
1655 | + * the metadata are committed. |
1656 | + */ |
1657 | + dm_pool_pre_commit_fn pre_commit_fn; |
1658 | + void *pre_commit_context; |
1659 | + |
1660 | /* |
1661 | * We reserve a section of the metadata for commit overhead. |
1662 | * All reported space does *not* include this. |
1663 | @@ -826,6 +835,14 @@ static int __commit_transaction(struct dm_pool_metadata *pmd) |
1664 | if (unlikely(!pmd->in_service)) |
1665 | return 0; |
1666 | |
1667 | + if (pmd->pre_commit_fn) { |
1668 | + r = pmd->pre_commit_fn(pmd->pre_commit_context); |
1669 | + if (r < 0) { |
1670 | + DMERR("pre-commit callback failed"); |
1671 | + return r; |
1672 | + } |
1673 | + } |
1674 | + |
1675 | r = __write_changed_details(pmd); |
1676 | if (r < 0) |
1677 | return r; |
1678 | @@ -892,6 +909,8 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev, |
1679 | pmd->in_service = false; |
1680 | pmd->bdev = bdev; |
1681 | pmd->data_block_size = data_block_size; |
1682 | + pmd->pre_commit_fn = NULL; |
1683 | + pmd->pre_commit_context = NULL; |
1684 | |
1685 | r = __create_persistent_data_objects(pmd, format_device); |
1686 | if (r) { |
1687 | @@ -2044,6 +2063,16 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd, |
1688 | return r; |
1689 | } |
1690 | |
1691 | +void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd, |
1692 | + dm_pool_pre_commit_fn fn, |
1693 | + void *context) |
1694 | +{ |
1695 | + pmd_write_lock_in_core(pmd); |
1696 | + pmd->pre_commit_fn = fn; |
1697 | + pmd->pre_commit_context = context; |
1698 | + pmd_write_unlock(pmd); |
1699 | +} |
1700 | + |
1701 | int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd) |
1702 | { |
1703 | int r = -EINVAL; |
1704 | diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h |
1705 | index f6be0d733c20..7ef56bd2a7e3 100644 |
1706 | --- a/drivers/md/dm-thin-metadata.h |
1707 | +++ b/drivers/md/dm-thin-metadata.h |
1708 | @@ -230,6 +230,13 @@ bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd); |
1709 | */ |
1710 | void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd); |
1711 | |
1712 | +/* Pre-commit callback */ |
1713 | +typedef int (*dm_pool_pre_commit_fn)(void *context); |
1714 | + |
1715 | +void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd, |
1716 | + dm_pool_pre_commit_fn fn, |
1717 | + void *context); |
1718 | + |
1719 | /*----------------------------------------------------------------*/ |
1720 | |
1721 | #endif |
1722 | diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c |
1723 | index fcd887703f95..1696bfd23ad1 100644 |
1724 | --- a/drivers/md/dm-thin.c |
1725 | +++ b/drivers/md/dm-thin.c |
1726 | @@ -328,6 +328,7 @@ struct pool_c { |
1727 | dm_block_t low_water_blocks; |
1728 | struct pool_features requested_pf; /* Features requested during table load */ |
1729 | struct pool_features adjusted_pf; /* Features used after adjusting for constituent devices */ |
1730 | + struct bio flush_bio; |
1731 | }; |
1732 | |
1733 | /* |
1734 | @@ -2392,8 +2393,16 @@ static void process_deferred_bios(struct pool *pool) |
1735 | while ((bio = bio_list_pop(&bio_completions))) |
1736 | bio_endio(bio); |
1737 | |
1738 | - while ((bio = bio_list_pop(&bios))) |
1739 | - generic_make_request(bio); |
1740 | + while ((bio = bio_list_pop(&bios))) { |
1741 | + /* |
1742 | + * The data device was flushed as part of metadata commit, |
1743 | + * so complete redundant flushes immediately. |
1744 | + */ |
1745 | + if (bio->bi_opf & REQ_PREFLUSH) |
1746 | + bio_endio(bio); |
1747 | + else |
1748 | + generic_make_request(bio); |
1749 | + } |
1750 | } |
1751 | |
1752 | static void do_worker(struct work_struct *ws) |
1753 | @@ -3127,6 +3136,7 @@ static void pool_dtr(struct dm_target *ti) |
1754 | __pool_dec(pt->pool); |
1755 | dm_put_device(ti, pt->metadata_dev); |
1756 | dm_put_device(ti, pt->data_dev); |
1757 | + bio_uninit(&pt->flush_bio); |
1758 | kfree(pt); |
1759 | |
1760 | mutex_unlock(&dm_thin_pool_table.mutex); |
1761 | @@ -3192,6 +3202,29 @@ static void metadata_low_callback(void *context) |
1762 | dm_table_event(pool->ti->table); |
1763 | } |
1764 | |
1765 | +/* |
1766 | + * We need to flush the data device **before** committing the metadata. |
1767 | + * |
1768 | + * This ensures that the data blocks of any newly inserted mappings are |
1769 | + * properly written to non-volatile storage and won't be lost in case of a |
1770 | + * crash. |
1771 | + * |
1772 | + * Failure to do so can result in data corruption in the case of internal or |
1773 | + * external snapshots and in the case of newly provisioned blocks, when block |
1774 | + * zeroing is enabled. |
1775 | + */ |
1776 | +static int metadata_pre_commit_callback(void *context) |
1777 | +{ |
1778 | + struct pool_c *pt = context; |
1779 | + struct bio *flush_bio = &pt->flush_bio; |
1780 | + |
1781 | + bio_reset(flush_bio); |
1782 | + bio_set_dev(flush_bio, pt->data_dev->bdev); |
1783 | + flush_bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; |
1784 | + |
1785 | + return submit_bio_wait(flush_bio); |
1786 | +} |
1787 | + |
1788 | static sector_t get_dev_size(struct block_device *bdev) |
1789 | { |
1790 | return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; |
1791 | @@ -3360,6 +3393,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) |
1792 | pt->data_dev = data_dev; |
1793 | pt->low_water_blocks = low_water_blocks; |
1794 | pt->adjusted_pf = pt->requested_pf = pf; |
1795 | + bio_init(&pt->flush_bio, NULL, 0); |
1796 | ti->num_flush_bios = 1; |
1797 | |
1798 | /* |
1799 | @@ -3386,6 +3420,10 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) |
1800 | if (r) |
1801 | goto out_flags_changed; |
1802 | |
1803 | + dm_pool_register_pre_commit_callback(pt->pool->pmd, |
1804 | + metadata_pre_commit_callback, |
1805 | + pt); |
1806 | + |
1807 | pt->callbacks.congested_fn = pool_is_congested; |
1808 | dm_table_add_target_callbacks(ti->table, &pt->callbacks); |
1809 | |
1810 | diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c |
1811 | index 21ea537bd55e..eff04fa23dfa 100644 |
1812 | --- a/drivers/md/persistent-data/dm-btree-remove.c |
1813 | +++ b/drivers/md/persistent-data/dm-btree-remove.c |
1814 | @@ -203,7 +203,13 @@ static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent, |
1815 | struct btree_node *right = r->n; |
1816 | uint32_t nr_left = le32_to_cpu(left->header.nr_entries); |
1817 | uint32_t nr_right = le32_to_cpu(right->header.nr_entries); |
1818 | - unsigned threshold = 2 * merge_threshold(left) + 1; |
1819 | + /* |
1820 | + * Ensure the number of entries in each child will be greater |
1821 | + * than or equal to (max_entries / 3 + 1), so no matter which |
1822 | + * child is used for removal, the number will still be not |
1823 | + * less than (max_entries / 3). |
1824 | + */ |
1825 | + unsigned int threshold = 2 * (merge_threshold(left) + 1); |
1826 | |
1827 | if (nr_left + nr_right < threshold) { |
1828 | /* |
1829 | diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c |
1830 | index 2c71a434c915..95b41c0891d0 100644 |
1831 | --- a/drivers/mmc/core/block.c |
1832 | +++ b/drivers/mmc/core/block.c |
1833 | @@ -408,38 +408,6 @@ static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr, |
1834 | return 0; |
1835 | } |
1836 | |
1837 | -static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status, |
1838 | - u32 retries_max) |
1839 | -{ |
1840 | - int err; |
1841 | - u32 retry_count = 0; |
1842 | - |
1843 | - if (!status || !retries_max) |
1844 | - return -EINVAL; |
1845 | - |
1846 | - do { |
1847 | - err = __mmc_send_status(card, status, 5); |
1848 | - if (err) |
1849 | - break; |
1850 | - |
1851 | - if (!R1_STATUS(*status) && |
1852 | - (R1_CURRENT_STATE(*status) != R1_STATE_PRG)) |
1853 | - break; /* RPMB programming operation complete */ |
1854 | - |
1855 | - /* |
1856 | - * Rechedule to give the MMC device a chance to continue |
1857 | - * processing the previous command without being polled too |
1858 | - * frequently. |
1859 | - */ |
1860 | - usleep_range(1000, 5000); |
1861 | - } while (++retry_count < retries_max); |
1862 | - |
1863 | - if (retry_count == retries_max) |
1864 | - err = -EPERM; |
1865 | - |
1866 | - return err; |
1867 | -} |
1868 | - |
1869 | static int ioctl_do_sanitize(struct mmc_card *card) |
1870 | { |
1871 | int err; |
1872 | @@ -468,6 +436,58 @@ out: |
1873 | return err; |
1874 | } |
1875 | |
1876 | +static inline bool mmc_blk_in_tran_state(u32 status) |
1877 | +{ |
1878 | + /* |
1879 | + * Some cards mishandle the status bits, so make sure to check both the |
1880 | + * busy indication and the card state. |
1881 | + */ |
1882 | + return status & R1_READY_FOR_DATA && |
1883 | + (R1_CURRENT_STATE(status) == R1_STATE_TRAN); |
1884 | +} |
1885 | + |
1886 | +static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms, |
1887 | + u32 *resp_errs) |
1888 | +{ |
1889 | + unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); |
1890 | + int err = 0; |
1891 | + u32 status; |
1892 | + |
1893 | + do { |
1894 | + bool done = time_after(jiffies, timeout); |
1895 | + |
1896 | + err = __mmc_send_status(card, &status, 5); |
1897 | + if (err) { |
1898 | + dev_err(mmc_dev(card->host), |
1899 | + "error %d requesting status\n", err); |
1900 | + return err; |
1901 | + } |
1902 | + |
1903 | + /* Accumulate any response error bits seen */ |
1904 | + if (resp_errs) |
1905 | + *resp_errs |= status; |
1906 | + |
1907 | + /* |
1908 | + * Timeout if the device never becomes ready for data and never |
1909 | + * leaves the program state. |
1910 | + */ |
1911 | + if (done) { |
1912 | + dev_err(mmc_dev(card->host), |
1913 | + "Card stuck in wrong state! %s status: %#x\n", |
1914 | + __func__, status); |
1915 | + return -ETIMEDOUT; |
1916 | + } |
1917 | + |
1918 | + /* |
1919 | + * Some cards mishandle the status bits, |
1920 | + * so make sure to check both the busy |
1921 | + * indication and the card state. |
1922 | + */ |
1923 | + } while (!mmc_blk_in_tran_state(status)); |
1924 | + |
1925 | + return err; |
1926 | +} |
1927 | + |
1928 | static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, |
1929 | struct mmc_blk_ioc_data *idata) |
1930 | { |
1931 | @@ -477,7 +497,6 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, |
1932 | struct scatterlist sg; |
1933 | int err; |
1934 | unsigned int target_part; |
1935 | - u32 status = 0; |
1936 | |
1937 | if (!card || !md || !idata) |
1938 | return -EINVAL; |
1939 | @@ -611,16 +630,12 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, |
1940 | |
1941 | memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp)); |
1942 | |
1943 | - if (idata->rpmb) { |
1944 | + if (idata->rpmb || (cmd.flags & MMC_RSP_R1B)) { |
1945 | /* |
1946 | - * Ensure RPMB command has completed by polling CMD13 |
1947 | + * Ensure RPMB/R1B command has completed by polling CMD13 |
1948 | * "Send Status". |
1949 | */ |
1950 | - err = ioctl_rpmb_card_status_poll(card, &status, 5); |
1951 | - if (err) |
1952 | - dev_err(mmc_dev(card->host), |
1953 | - "%s: Card Status=0x%08X, error %d\n", |
1954 | - __func__, status, err); |
1955 | + err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, NULL); |
1956 | } |
1957 | |
1958 | return err; |
1959 | @@ -970,58 +985,6 @@ static unsigned int mmc_blk_data_timeout_ms(struct mmc_host *host, |
1960 | return ms; |
1961 | } |
1962 | |
1963 | -static inline bool mmc_blk_in_tran_state(u32 status) |
1964 | -{ |
1965 | - /* |
1966 | - * Some cards mishandle the status bits, so make sure to check both the |
1967 | - * busy indication and the card state. |
1968 | - */ |
1969 | - return status & R1_READY_FOR_DATA && |
1970 | - (R1_CURRENT_STATE(status) == R1_STATE_TRAN); |
1971 | -} |
1972 | - |
1973 | -static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms, |
1974 | - struct request *req, u32 *resp_errs) |
1975 | -{ |
1976 | - unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); |
1977 | - int err = 0; |
1978 | - u32 status; |
1979 | - |
1980 | - do { |
1981 | - bool done = time_after(jiffies, timeout); |
1982 | - |
1983 | - err = __mmc_send_status(card, &status, 5); |
1984 | - if (err) { |
1985 | - pr_err("%s: error %d requesting status\n", |
1986 | - req->rq_disk->disk_name, err); |
1987 | - return err; |
1988 | - } |
1989 | - |
1990 | - /* Accumulate any response error bits seen */ |
1991 | - if (resp_errs) |
1992 | - *resp_errs |= status; |
1993 | - |
1994 | - /* |
1995 | - * Timeout if the device never becomes ready for data and never |
1996 | - * leaves the program state. |
1997 | - */ |
1998 | - if (done) { |
1999 | - pr_err("%s: Card stuck in wrong state! %s %s status: %#x\n", |
2000 | - mmc_hostname(card->host), |
2001 | - req->rq_disk->disk_name, __func__, status); |
2002 | - return -ETIMEDOUT; |
2003 | - } |
2004 | - |
2005 | - /* |
2006 | - * Some cards mishandle the status bits, |
2007 | - * so make sure to check both the busy |
2008 | - * indication and the card state. |
2009 | - */ |
2010 | - } while (!mmc_blk_in_tran_state(status)); |
2011 | - |
2012 | - return err; |
2013 | -} |
2014 | - |
2015 | static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host, |
2016 | int type) |
2017 | { |
2018 | @@ -1671,7 +1634,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req) |
2019 | |
2020 | mmc_blk_send_stop(card, timeout); |
2021 | |
2022 | - err = card_busy_detect(card, timeout, req, NULL); |
2023 | + err = card_busy_detect(card, timeout, NULL); |
2024 | |
2025 | mmc_retune_release(card->host); |
2026 | |
2027 | @@ -1895,7 +1858,7 @@ static int mmc_blk_card_busy(struct mmc_card *card, struct request *req) |
2028 | if (mmc_host_is_spi(card->host) || rq_data_dir(req) == READ) |
2029 | return 0; |
2030 | |
2031 | - err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, req, &status); |
2032 | + err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, &status); |
2033 | |
2034 | /* |
2035 | * Do not assume data transferred correctly if there are any error bits |
2036 | diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c |
2037 | index 221127324709..abf8f5eb0a1c 100644 |
2038 | --- a/drivers/mmc/core/core.c |
2039 | +++ b/drivers/mmc/core/core.c |
2040 | @@ -1469,8 +1469,7 @@ void mmc_detach_bus(struct mmc_host *host) |
2041 | mmc_bus_put(host); |
2042 | } |
2043 | |
2044 | -static void _mmc_detect_change(struct mmc_host *host, unsigned long delay, |
2045 | - bool cd_irq) |
2046 | +void _mmc_detect_change(struct mmc_host *host, unsigned long delay, bool cd_irq) |
2047 | { |
2048 | /* |
2049 | * If the device is configured as wakeup, we prevent a new sleep for |
2050 | @@ -2129,7 +2128,7 @@ int mmc_hw_reset(struct mmc_host *host) |
2051 | ret = host->bus_ops->hw_reset(host); |
2052 | mmc_bus_put(host); |
2053 | |
2054 | - if (ret) |
2055 | + if (ret < 0) |
2056 | pr_warn("%s: tried to HW reset card, got error %d\n", |
2057 | mmc_hostname(host), ret); |
2058 | |
2059 | @@ -2297,11 +2296,8 @@ void mmc_rescan(struct work_struct *work) |
2060 | |
2061 | mmc_bus_get(host); |
2062 | |
2063 | - /* |
2064 | - * if there is a _removable_ card registered, check whether it is |
2065 | - * still present |
2066 | - */ |
2067 | - if (host->bus_ops && !host->bus_dead && mmc_card_is_removable(host)) |
2068 | + /* Verify a registered card to be functional, else remove it. */ |
2069 | + if (host->bus_ops && !host->bus_dead) |
2070 | host->bus_ops->detect(host); |
2071 | |
2072 | host->detect_change = 0; |
2073 | diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h |
2074 | index 328c78dbee66..575ac0257af2 100644 |
2075 | --- a/drivers/mmc/core/core.h |
2076 | +++ b/drivers/mmc/core/core.h |
2077 | @@ -70,6 +70,8 @@ void mmc_rescan(struct work_struct *work); |
2078 | void mmc_start_host(struct mmc_host *host); |
2079 | void mmc_stop_host(struct mmc_host *host); |
2080 | |
2081 | +void _mmc_detect_change(struct mmc_host *host, unsigned long delay, |
2082 | + bool cd_irq); |
2083 | int _mmc_detect_card_removed(struct mmc_host *host); |
2084 | int mmc_detect_card_removed(struct mmc_host *host); |
2085 | |
2086 | diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c |
2087 | index 26cabd53ddc5..ebb387aa5158 100644 |
2088 | --- a/drivers/mmc/core/sdio.c |
2089 | +++ b/drivers/mmc/core/sdio.c |
2090 | @@ -1048,9 +1048,35 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host) |
2091 | return ret; |
2092 | } |
2093 | |
2094 | +/* |
2095 | + * SDIO HW reset |
2096 | + * |
2097 | + * Returns 0 if the HW reset was executed synchronously, returns 1 if the HW |
2098 | + * reset was asynchronously scheduled, else a negative error code. |
2099 | + */ |
2100 | static int mmc_sdio_hw_reset(struct mmc_host *host) |
2101 | { |
2102 | - mmc_power_cycle(host, host->card->ocr); |
2103 | + struct mmc_card *card = host->card; |
2104 | + |
2105 | + /* |
2106 | + * In case the card is shared among multiple func drivers, reset the |
2107 | + * card through a rescan work. In this way it will be removed and |
2108 | + * re-detected, thus all func drivers becomes informed about it. |
2109 | + */ |
2110 | + if (atomic_read(&card->sdio_funcs_probed) > 1) { |
2111 | + if (mmc_card_removed(card)) |
2112 | + return 1; |
2113 | + host->rescan_entered = 0; |
2114 | + mmc_card_set_removed(card); |
2115 | + _mmc_detect_change(host, 0, false); |
2116 | + return 1; |
2117 | + } |
2118 | + |
2119 | + /* |
2120 | + * A single func driver has been probed, then let's skip the heavy |
2121 | + * hotplug dance above and execute the reset immediately. |
2122 | + */ |
2123 | + mmc_power_cycle(host, card->ocr); |
2124 | return mmc_sdio_reinit_card(host); |
2125 | } |
2126 | |
2127 | diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c |
2128 | index 2963e6542958..3cc928282af7 100644 |
2129 | --- a/drivers/mmc/core/sdio_bus.c |
2130 | +++ b/drivers/mmc/core/sdio_bus.c |
2131 | @@ -138,6 +138,8 @@ static int sdio_bus_probe(struct device *dev) |
2132 | if (ret) |
2133 | return ret; |
2134 | |
2135 | + atomic_inc(&func->card->sdio_funcs_probed); |
2136 | + |
2137 | /* Unbound SDIO functions are always suspended. |
2138 | * During probe, the function is set active and the usage count |
2139 | * is incremented. If the driver supports runtime PM, |
2140 | @@ -153,7 +155,10 @@ static int sdio_bus_probe(struct device *dev) |
2141 | /* Set the default block size so the driver is sure it's something |
2142 | * sensible. */ |
2143 | sdio_claim_host(func); |
2144 | - ret = sdio_set_block_size(func, 0); |
2145 | + if (mmc_card_removed(func->card)) |
2146 | + ret = -ENOMEDIUM; |
2147 | + else |
2148 | + ret = sdio_set_block_size(func, 0); |
2149 | sdio_release_host(func); |
2150 | if (ret) |
2151 | goto disable_runtimepm; |
2152 | @@ -165,6 +170,7 @@ static int sdio_bus_probe(struct device *dev) |
2153 | return 0; |
2154 | |
2155 | disable_runtimepm: |
2156 | + atomic_dec(&func->card->sdio_funcs_probed); |
2157 | if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) |
2158 | pm_runtime_put_noidle(dev); |
2159 | dev_pm_domain_detach(dev, false); |
2160 | @@ -181,6 +187,7 @@ static int sdio_bus_remove(struct device *dev) |
2161 | pm_runtime_get_sync(dev); |
2162 | |
2163 | drv->remove(func); |
2164 | + atomic_dec(&func->card->sdio_funcs_probed); |
2165 | |
2166 | if (func->irq_handler) { |
2167 | pr_warn("WARNING: driver %s did not remove its interrupt handler!\n", |
2168 | diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c |
2169 | index f6a669a9af41..1ad0b56f11b4 100644 |
2170 | --- a/drivers/pci/controller/pcie-rcar.c |
2171 | +++ b/drivers/pci/controller/pcie-rcar.c |
2172 | @@ -93,8 +93,11 @@ |
2173 | #define LINK_SPEED_2_5GTS (1 << 16) |
2174 | #define LINK_SPEED_5_0GTS (2 << 16) |
2175 | #define MACCTLR 0x011058 |
2176 | +#define MACCTLR_NFTS_MASK GENMASK(23, 16) /* The name is from SH7786 */ |
2177 | #define SPEED_CHANGE BIT(24) |
2178 | #define SCRAMBLE_DISABLE BIT(27) |
2179 | +#define LTSMDIS BIT(31) |
2180 | +#define MACCTLR_INIT_VAL (LTSMDIS | MACCTLR_NFTS_MASK) |
2181 | #define PMSR 0x01105c |
2182 | #define MACS2R 0x011078 |
2183 | #define MACCGSPSETR 0x011084 |
2184 | @@ -615,6 +618,8 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie) |
2185 | if (IS_ENABLED(CONFIG_PCI_MSI)) |
2186 | rcar_pci_write_reg(pcie, 0x801f0000, PCIEMSITXR); |
2187 | |
2188 | + rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR); |
2189 | + |
2190 | /* Finish initialization - establish a PCI Express link */ |
2191 | rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); |
2192 | |
2193 | @@ -1237,6 +1242,7 @@ static int rcar_pcie_resume_noirq(struct device *dev) |
2194 | return 0; |
2195 | |
2196 | /* Re-establish the PCIe link */ |
2197 | + rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR); |
2198 | rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); |
2199 | return rcar_pcie_wait_for_dl(pcie); |
2200 | } |
2201 | diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h |
2202 | index 654c972b8ea0..882ce82c4699 100644 |
2203 | --- a/drivers/pci/hotplug/pciehp.h |
2204 | +++ b/drivers/pci/hotplug/pciehp.h |
2205 | @@ -72,6 +72,7 @@ extern int pciehp_poll_time; |
2206 | * @reset_lock: prevents access to the Data Link Layer Link Active bit in the |
2207 | * Link Status register and to the Presence Detect State bit in the Slot |
2208 | * Status register during a slot reset which may cause them to flap |
2209 | + * @ist_running: flag to keep user request waiting while IRQ thread is running |
2210 | * @request_result: result of last user request submitted to the IRQ thread |
2211 | * @requester: wait queue to wake up on completion of user request, |
2212 | * used for synchronous slot enable/disable request via sysfs |
2213 | @@ -101,6 +102,7 @@ struct controller { |
2214 | |
2215 | struct hotplug_slot hotplug_slot; /* hotplug core interface */ |
2216 | struct rw_semaphore reset_lock; |
2217 | + unsigned int ist_running; |
2218 | int request_result; |
2219 | wait_queue_head_t requester; |
2220 | }; |
2221 | diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c |
2222 | index 21af7b16d7a4..dd8e4a5fb282 100644 |
2223 | --- a/drivers/pci/hotplug/pciehp_ctrl.c |
2224 | +++ b/drivers/pci/hotplug/pciehp_ctrl.c |
2225 | @@ -375,7 +375,8 @@ int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot) |
2226 | ctrl->request_result = -ENODEV; |
2227 | pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC); |
2228 | wait_event(ctrl->requester, |
2229 | - !atomic_read(&ctrl->pending_events)); |
2230 | + !atomic_read(&ctrl->pending_events) && |
2231 | + !ctrl->ist_running); |
2232 | return ctrl->request_result; |
2233 | case POWERON_STATE: |
2234 | ctrl_info(ctrl, "Slot(%s): Already in powering on state\n", |
2235 | @@ -408,7 +409,8 @@ int pciehp_sysfs_disable_slot(struct hotplug_slot *hotplug_slot) |
2236 | mutex_unlock(&ctrl->state_lock); |
2237 | pciehp_request(ctrl, DISABLE_SLOT); |
2238 | wait_event(ctrl->requester, |
2239 | - !atomic_read(&ctrl->pending_events)); |
2240 | + !atomic_read(&ctrl->pending_events) && |
2241 | + !ctrl->ist_running); |
2242 | return ctrl->request_result; |
2243 | case POWEROFF_STATE: |
2244 | ctrl_info(ctrl, "Slot(%s): Already in powering off state\n", |
2245 | diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c |
2246 | index 1a522c1c4177..86d97f3112f0 100644 |
2247 | --- a/drivers/pci/hotplug/pciehp_hpc.c |
2248 | +++ b/drivers/pci/hotplug/pciehp_hpc.c |
2249 | @@ -583,6 +583,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) |
2250 | irqreturn_t ret; |
2251 | u32 events; |
2252 | |
2253 | + ctrl->ist_running = true; |
2254 | pci_config_pm_runtime_get(pdev); |
2255 | |
2256 | /* rerun pciehp_isr() if the port was inaccessible on interrupt */ |
2257 | @@ -629,6 +630,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) |
2258 | up_read(&ctrl->reset_lock); |
2259 | |
2260 | pci_config_pm_runtime_put(pdev); |
2261 | + ctrl->ist_running = false; |
2262 | wake_up(&ctrl->requester); |
2263 | return IRQ_HANDLED; |
2264 | } |
2265 | diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c |
2266 | index 0884bedcfc7a..771041784e64 100644 |
2267 | --- a/drivers/pci/msi.c |
2268 | +++ b/drivers/pci/msi.c |
2269 | @@ -213,12 +213,13 @@ u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag) |
2270 | |
2271 | if (pci_msi_ignore_mask) |
2272 | return 0; |
2273 | + |
2274 | desc_addr = pci_msix_desc_addr(desc); |
2275 | if (!desc_addr) |
2276 | return 0; |
2277 | |
2278 | mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; |
2279 | - if (flag) |
2280 | + if (flag & PCI_MSIX_ENTRY_CTRL_MASKBIT) |
2281 | mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; |
2282 | |
2283 | writel(mask_bits, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); |
2284 | diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c |
2285 | index a8124e47bf6e..d4ac8ce8c1f9 100644 |
2286 | --- a/drivers/pci/pci-driver.c |
2287 | +++ b/drivers/pci/pci-driver.c |
2288 | @@ -1076,17 +1076,22 @@ static int pci_pm_thaw_noirq(struct device *dev) |
2289 | return error; |
2290 | } |
2291 | |
2292 | - if (pci_has_legacy_pm_support(pci_dev)) |
2293 | - return pci_legacy_resume_early(dev); |
2294 | - |
2295 | /* |
2296 | - * pci_restore_state() requires the device to be in D0 (because of MSI |
2297 | - * restoration among other things), so force it into D0 in case the |
2298 | - * driver's "freeze" callbacks put it into a low-power state directly. |
2299 | + * Both the legacy ->resume_early() and the new pm->thaw_noirq() |
2300 | + * callbacks assume the device has been returned to D0 and its |
2301 | + * config state has been restored. |
2302 | + * |
2303 | + * In addition, pci_restore_state() restores MSI-X state in MMIO |
2304 | + * space, which requires the device to be in D0, so return it to D0 |
2305 | + * in case the driver's "freeze" callbacks put it into a low-power |
2306 | + * state. |
2307 | */ |
2308 | pci_set_power_state(pci_dev, PCI_D0); |
2309 | pci_restore_state(pci_dev); |
2310 | |
2311 | + if (pci_has_legacy_pm_support(pci_dev)) |
2312 | + return pci_legacy_resume_early(dev); |
2313 | + |
2314 | if (drv && drv->pm && drv->pm->thaw_noirq) |
2315 | error = drv->pm->thaw_noirq(dev); |
2316 | |
2317 | diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c |
2318 | index 3d5271a7a849..64ebe3e5e611 100644 |
2319 | --- a/drivers/pci/probe.c |
2320 | +++ b/drivers/pci/probe.c |
2321 | @@ -1089,14 +1089,15 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, |
2322 | * @sec: updated with secondary bus number from EA |
2323 | * @sub: updated with subordinate bus number from EA |
2324 | * |
2325 | - * If @dev is a bridge with EA capability, update @sec and @sub with |
2326 | - * fixed bus numbers from the capability and return true. Otherwise, |
2327 | - * return false. |
2328 | + * If @dev is a bridge with EA capability that specifies valid secondary |
2329 | + * and subordinate bus numbers, return true with the bus numbers in @sec |
2330 | + * and @sub. Otherwise return false. |
2331 | */ |
2332 | static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub) |
2333 | { |
2334 | int ea, offset; |
2335 | u32 dw; |
2336 | + u8 ea_sec, ea_sub; |
2337 | |
2338 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) |
2339 | return false; |
2340 | @@ -1108,8 +1109,13 @@ static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub) |
2341 | |
2342 | offset = ea + PCI_EA_FIRST_ENT; |
2343 | pci_read_config_dword(dev, offset, &dw); |
2344 | - *sec = dw & PCI_EA_SEC_BUS_MASK; |
2345 | - *sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT; |
2346 | + ea_sec = dw & PCI_EA_SEC_BUS_MASK; |
2347 | + ea_sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT; |
2348 | + if (ea_sec == 0 || ea_sub < ea_sec) |
2349 | + return false; |
2350 | + |
2351 | + *sec = ea_sec; |
2352 | + *sub = ea_sub; |
2353 | return true; |
2354 | } |
2355 | |
2356 | diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c |
2357 | index 320255e5e8f8..308f744393eb 100644 |
2358 | --- a/drivers/pci/quirks.c |
2359 | +++ b/drivers/pci/quirks.c |
2360 | @@ -4313,15 +4313,21 @@ static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags) |
2361 | |
2362 | static bool pci_quirk_cavium_acs_match(struct pci_dev *dev) |
2363 | { |
2364 | + if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) |
2365 | + return false; |
2366 | + |
2367 | + switch (dev->device) { |
2368 | /* |
2369 | - * Effectively selects all downstream ports for whole ThunderX 1 |
2370 | - * family by 0xf800 mask (which represents 8 SoCs), while the lower |
2371 | - * bits of device ID are used to indicate which subdevice is used |
2372 | - * within the SoC. |
2373 | + * Effectively selects all downstream ports for whole ThunderX1 |
2374 | + * (which represents 8 SoCs). |
2375 | */ |
2376 | - return (pci_is_pcie(dev) && |
2377 | - (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) && |
2378 | - ((dev->device & 0xf800) == 0xa000)); |
2379 | + case 0xa000 ... 0xa7ff: /* ThunderX1 */ |
2380 | + case 0xaf84: /* ThunderX2 */ |
2381 | + case 0xb884: /* ThunderX3 */ |
2382 | + return true; |
2383 | + default: |
2384 | + return false; |
2385 | + } |
2386 | } |
2387 | |
2388 | static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags) |
2389 | @@ -4706,7 +4712,7 @@ int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags) |
2390 | #define INTEL_BSPR_REG_BPPD (1 << 9) |
2391 | |
2392 | /* Upstream Peer Decode Configuration Register */ |
2393 | -#define INTEL_UPDCR_REG 0x1114 |
2394 | +#define INTEL_UPDCR_REG 0x1014 |
2395 | /* 5:0 Peer Decode Enable bits */ |
2396 | #define INTEL_UPDCR_REG_MASK 0x3f |
2397 | |
2398 | diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c |
2399 | index 8c94cd3fd1f2..465d6afd826e 100644 |
2400 | --- a/drivers/pci/switch/switchtec.c |
2401 | +++ b/drivers/pci/switch/switchtec.c |
2402 | @@ -675,7 +675,7 @@ static int ioctl_event_summary(struct switchtec_dev *stdev, |
2403 | return -ENOMEM; |
2404 | |
2405 | s->global = ioread32(&stdev->mmio_sw_event->global_summary); |
2406 | - s->part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap); |
2407 | + s->part_bitmap = ioread64(&stdev->mmio_sw_event->part_event_bitmap); |
2408 | s->local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary); |
2409 | |
2410 | for (i = 0; i < stdev->partition_count; i++) { |
2411 | diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c |
2412 | index 621f1afd4d6b..1995f5b3ea67 100644 |
2413 | --- a/drivers/rpmsg/qcom_glink_native.c |
2414 | +++ b/drivers/rpmsg/qcom_glink_native.c |
2415 | @@ -241,10 +241,31 @@ static void qcom_glink_channel_release(struct kref *ref) |
2416 | { |
2417 | struct glink_channel *channel = container_of(ref, struct glink_channel, |
2418 | refcount); |
2419 | + struct glink_core_rx_intent *intent; |
2420 | + struct glink_core_rx_intent *tmp; |
2421 | unsigned long flags; |
2422 | + int iid; |
2423 | + |
2424 | + /* cancel pending rx_done work */ |
2425 | + cancel_work_sync(&channel->intent_work); |
2426 | |
2427 | spin_lock_irqsave(&channel->intent_lock, flags); |
2428 | + /* Free all non-reuse intents pending rx_done work */ |
2429 | + list_for_each_entry_safe(intent, tmp, &channel->done_intents, node) { |
2430 | + if (!intent->reuse) { |
2431 | + kfree(intent->data); |
2432 | + kfree(intent); |
2433 | + } |
2434 | + } |
2435 | + |
2436 | + idr_for_each_entry(&channel->liids, tmp, iid) { |
2437 | + kfree(tmp->data); |
2438 | + kfree(tmp); |
2439 | + } |
2440 | idr_destroy(&channel->liids); |
2441 | + |
2442 | + idr_for_each_entry(&channel->riids, tmp, iid) |
2443 | + kfree(tmp); |
2444 | idr_destroy(&channel->riids); |
2445 | spin_unlock_irqrestore(&channel->intent_lock, flags); |
2446 | |
2447 | @@ -1094,13 +1115,12 @@ static int qcom_glink_create_remote(struct qcom_glink *glink, |
2448 | close_link: |
2449 | /* |
2450 | * Send a close request to "undo" our open-ack. The close-ack will |
2451 | - * release the last reference. |
2452 | + * release qcom_glink_send_open_req() reference and the last reference |
2453 | + * will be relesed after receiving remote_close or transport unregister |
2454 | + * by calling qcom_glink_native_remove(). |
2455 | */ |
2456 | qcom_glink_send_close_req(glink, channel); |
2457 | |
2458 | - /* Release qcom_glink_send_open_req() reference */ |
2459 | - kref_put(&channel->refcount, qcom_glink_channel_release); |
2460 | - |
2461 | return ret; |
2462 | } |
2463 | |
2464 | @@ -1415,15 +1435,13 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid, |
2465 | |
2466 | ret = rpmsg_register_device(rpdev); |
2467 | if (ret) |
2468 | - goto free_rpdev; |
2469 | + goto rcid_remove; |
2470 | |
2471 | channel->rpdev = rpdev; |
2472 | } |
2473 | |
2474 | return 0; |
2475 | |
2476 | -free_rpdev: |
2477 | - kfree(rpdev); |
2478 | rcid_remove: |
2479 | spin_lock_irqsave(&glink->idr_lock, flags); |
2480 | idr_remove(&glink->rcids, channel->rcid); |
2481 | @@ -1544,6 +1562,18 @@ static void qcom_glink_work(struct work_struct *work) |
2482 | } |
2483 | } |
2484 | |
2485 | +static void qcom_glink_cancel_rx_work(struct qcom_glink *glink) |
2486 | +{ |
2487 | + struct glink_defer_cmd *dcmd; |
2488 | + struct glink_defer_cmd *tmp; |
2489 | + |
2490 | + /* cancel any pending deferred rx_work */ |
2491 | + cancel_work_sync(&glink->rx_work); |
2492 | + |
2493 | + list_for_each_entry_safe(dcmd, tmp, &glink->rx_queue, node) |
2494 | + kfree(dcmd); |
2495 | +} |
2496 | + |
2497 | struct qcom_glink *qcom_glink_native_probe(struct device *dev, |
2498 | unsigned long features, |
2499 | struct qcom_glink_pipe *rx, |
2500 | @@ -1619,23 +1649,24 @@ void qcom_glink_native_remove(struct qcom_glink *glink) |
2501 | struct glink_channel *channel; |
2502 | int cid; |
2503 | int ret; |
2504 | - unsigned long flags; |
2505 | |
2506 | disable_irq(glink->irq); |
2507 | - cancel_work_sync(&glink->rx_work); |
2508 | + qcom_glink_cancel_rx_work(glink); |
2509 | |
2510 | ret = device_for_each_child(glink->dev, NULL, qcom_glink_remove_device); |
2511 | if (ret) |
2512 | dev_warn(glink->dev, "Can't remove GLINK devices: %d\n", ret); |
2513 | |
2514 | - spin_lock_irqsave(&glink->idr_lock, flags); |
2515 | /* Release any defunct local channels, waiting for close-ack */ |
2516 | idr_for_each_entry(&glink->lcids, channel, cid) |
2517 | kref_put(&channel->refcount, qcom_glink_channel_release); |
2518 | |
2519 | + /* Release any defunct local channels, waiting for close-req */ |
2520 | + idr_for_each_entry(&glink->rcids, channel, cid) |
2521 | + kref_put(&channel->refcount, qcom_glink_channel_release); |
2522 | + |
2523 | idr_destroy(&glink->lcids); |
2524 | idr_destroy(&glink->rcids); |
2525 | - spin_unlock_irqrestore(&glink->idr_lock, flags); |
2526 | mbox_free_channel(glink->mbox_chan); |
2527 | } |
2528 | EXPORT_SYMBOL_GPL(qcom_glink_native_remove); |
2529 | diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c |
2530 | index 4238383d8685..579bc4443f6d 100644 |
2531 | --- a/drivers/rpmsg/qcom_glink_smem.c |
2532 | +++ b/drivers/rpmsg/qcom_glink_smem.c |
2533 | @@ -105,7 +105,7 @@ static void glink_smem_rx_advance(struct qcom_glink_pipe *np, |
2534 | tail = le32_to_cpu(*pipe->tail); |
2535 | |
2536 | tail += count; |
2537 | - if (tail > pipe->native.length) |
2538 | + if (tail >= pipe->native.length) |
2539 | tail -= pipe->native.length; |
2540 | |
2541 | *pipe->tail = cpu_to_le32(tail); |
2542 | diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c |
2543 | index ebd47c0cf9e9..70b99c0e2e67 100644 |
2544 | --- a/drivers/scsi/libiscsi.c |
2545 | +++ b/drivers/scsi/libiscsi.c |
2546 | @@ -1945,7 +1945,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) |
2547 | |
2548 | ISCSI_DBG_EH(session, "scsi cmd %p timedout\n", sc); |
2549 | |
2550 | - spin_lock(&session->frwd_lock); |
2551 | + spin_lock_bh(&session->frwd_lock); |
2552 | task = (struct iscsi_task *)sc->SCp.ptr; |
2553 | if (!task) { |
2554 | /* |
2555 | @@ -2072,7 +2072,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) |
2556 | done: |
2557 | if (task) |
2558 | task->last_timeout = jiffies; |
2559 | - spin_unlock(&session->frwd_lock); |
2560 | + spin_unlock_bh(&session->frwd_lock); |
2561 | ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? |
2562 | "timer reset" : "shutdown or nh"); |
2563 | return rc; |
2564 | diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c |
2565 | index 7259bce85e0e..1fbc5c6c6c14 100644 |
2566 | --- a/drivers/scsi/qla2xxx/qla_attr.c |
2567 | +++ b/drivers/scsi/qla2xxx/qla_attr.c |
2568 | @@ -176,6 +176,7 @@ qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, |
2569 | |
2570 | faddr = ha->flt_region_nvram; |
2571 | if (IS_QLA28XX(ha)) { |
2572 | + qla28xx_get_aux_images(vha, &active_regions); |
2573 | if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) |
2574 | faddr = ha->flt_region_nvram_sec; |
2575 | } |
2576 | diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c |
2577 | index 99f0a1a08143..cbaf178fc979 100644 |
2578 | --- a/drivers/scsi/qla2xxx/qla_bsg.c |
2579 | +++ b/drivers/scsi/qla2xxx/qla_bsg.c |
2580 | @@ -2399,7 +2399,7 @@ qla2x00_get_flash_image_status(struct bsg_job *bsg_job) |
2581 | struct qla_active_regions regions = { }; |
2582 | struct active_regions active_regions = { }; |
2583 | |
2584 | - qla28xx_get_aux_images(vha, &active_regions); |
2585 | + qla27xx_get_active_image(vha, &active_regions); |
2586 | regions.global_image = active_regions.global; |
2587 | |
2588 | if (IS_QLA28XX(ha)) { |
2589 | diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h |
2590 | index 732bb871c433..dc2366a29665 100644 |
2591 | --- a/drivers/scsi/qla2xxx/qla_fw.h |
2592 | +++ b/drivers/scsi/qla2xxx/qla_fw.h |
2593 | @@ -1523,6 +1523,10 @@ struct qla_flt_header { |
2594 | #define FLT_REG_NVRAM_SEC_28XX_1 0x10F |
2595 | #define FLT_REG_NVRAM_SEC_28XX_2 0x111 |
2596 | #define FLT_REG_NVRAM_SEC_28XX_3 0x113 |
2597 | +#define FLT_REG_MPI_PRI_28XX 0xD3 |
2598 | +#define FLT_REG_MPI_SEC_28XX 0xF0 |
2599 | +#define FLT_REG_PEP_PRI_28XX 0xD1 |
2600 | +#define FLT_REG_PEP_SEC_28XX 0xF1 |
2601 | |
2602 | struct qla_flt_region { |
2603 | uint16_t code; |
2604 | diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c |
2605 | index d400b51929a6..5d31e3d52b6b 100644 |
2606 | --- a/drivers/scsi/qla2xxx/qla_init.c |
2607 | +++ b/drivers/scsi/qla2xxx/qla_init.c |
2608 | @@ -534,6 +534,7 @@ static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport) |
2609 | |
2610 | e->u.fcport.fcport = fcport; |
2611 | fcport->flags |= FCF_ASYNC_ACTIVE; |
2612 | + fcport->disc_state = DSC_LOGIN_PEND; |
2613 | return qla2x00_post_work(vha, e); |
2614 | } |
2615 | |
2616 | @@ -4847,6 +4848,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) |
2617 | } |
2618 | |
2619 | INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn); |
2620 | + INIT_WORK(&fcport->free_work, qlt_free_session_done); |
2621 | INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); |
2622 | INIT_LIST_HEAD(&fcport->gnl_entry); |
2623 | INIT_LIST_HEAD(&fcport->list); |
2624 | diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c |
2625 | index f2d5115b2d8d..bbe90354f49b 100644 |
2626 | --- a/drivers/scsi/qla2xxx/qla_sup.c |
2627 | +++ b/drivers/scsi/qla2xxx/qla_sup.c |
2628 | @@ -847,15 +847,15 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) |
2629 | ha->flt_region_img_status_pri = start; |
2630 | break; |
2631 | case FLT_REG_IMG_SEC_27XX: |
2632 | - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
2633 | + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
2634 | ha->flt_region_img_status_sec = start; |
2635 | break; |
2636 | case FLT_REG_FW_SEC_27XX: |
2637 | - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
2638 | + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
2639 | ha->flt_region_fw_sec = start; |
2640 | break; |
2641 | case FLT_REG_BOOTLOAD_SEC_27XX: |
2642 | - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
2643 | + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
2644 | ha->flt_region_boot_sec = start; |
2645 | break; |
2646 | case FLT_REG_AUX_IMG_PRI_28XX: |
2647 | @@ -2725,8 +2725,11 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, |
2648 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, |
2649 | "Region %x is secure\n", region.code); |
2650 | |
2651 | - if (region.code == FLT_REG_FW || |
2652 | - region.code == FLT_REG_FW_SEC_27XX) { |
2653 | + switch (region.code) { |
2654 | + case FLT_REG_FW: |
2655 | + case FLT_REG_FW_SEC_27XX: |
2656 | + case FLT_REG_MPI_PRI_28XX: |
2657 | + case FLT_REG_MPI_SEC_28XX: |
2658 | fw_array = dwptr; |
2659 | |
2660 | /* 1st fw array */ |
2661 | @@ -2757,9 +2760,23 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, |
2662 | buf_size_without_sfub += risc_size; |
2663 | fw_array += risc_size; |
2664 | } |
2665 | - } else { |
2666 | - ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, |
2667 | - "Secure region %x not supported\n", |
2668 | + break; |
2669 | + |
2670 | + case FLT_REG_PEP_PRI_28XX: |
2671 | + case FLT_REG_PEP_SEC_28XX: |
2672 | + fw_array = dwptr; |
2673 | + |
2674 | + /* 1st fw array */ |
2675 | + risc_size = be32_to_cpu(fw_array[3]); |
2676 | + risc_attr = be32_to_cpu(fw_array[9]); |
2677 | + |
2678 | + buf_size_without_sfub = risc_size; |
2679 | + fw_array += risc_size; |
2680 | + break; |
2681 | + |
2682 | + default: |
2683 | + ql_log(ql_log_warn + ql_dbg_verbose, vha, |
2684 | + 0xffff, "Secure region %x not supported\n", |
2685 | region.code); |
2686 | rval = QLA_COMMAND_ERROR; |
2687 | goto done; |
2688 | @@ -2880,7 +2897,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, |
2689 | "Sending Secure Flash MB Cmd\n"); |
2690 | rval = qla28xx_secure_flash_update(vha, 0, region.code, |
2691 | buf_size_without_sfub, sfub_dma, |
2692 | - sizeof(struct secure_flash_update_block)); |
2693 | + sizeof(struct secure_flash_update_block) >> 2); |
2694 | if (rval != QLA_SUCCESS) { |
2695 | ql_log(ql_log_warn, vha, 0xffff, |
2696 | "Secure Flash MB Cmd failed %x.", rval); |
2697 | diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c |
2698 | index a06e56224a55..a9bd0f513316 100644 |
2699 | --- a/drivers/scsi/qla2xxx/qla_target.c |
2700 | +++ b/drivers/scsi/qla2xxx/qla_target.c |
2701 | @@ -1160,7 +1160,6 @@ void qlt_unreg_sess(struct fc_port *sess) |
2702 | sess->last_rscn_gen = sess->rscn_gen; |
2703 | sess->last_login_gen = sess->login_gen; |
2704 | |
2705 | - INIT_WORK(&sess->free_work, qlt_free_session_done); |
2706 | queue_work(sess->vha->hw->wq, &sess->free_work); |
2707 | } |
2708 | EXPORT_SYMBOL(qlt_unreg_sess); |
2709 | diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c |
2710 | index 042a24314edc..bab2073c1f72 100644 |
2711 | --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c |
2712 | +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c |
2713 | @@ -246,6 +246,8 @@ static void tcm_qla2xxx_complete_mcmd(struct work_struct *work) |
2714 | */ |
2715 | static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) |
2716 | { |
2717 | + if (!mcmd) |
2718 | + return; |
2719 | INIT_WORK(&mcmd->free_work, tcm_qla2xxx_complete_mcmd); |
2720 | queue_work(tcm_qla2xxx_free_wq, &mcmd->free_work); |
2721 | } |
2722 | diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c |
2723 | index b2af04c57a39..6feeb0faf123 100644 |
2724 | --- a/drivers/scsi/ufs/cdns-pltfrm.c |
2725 | +++ b/drivers/scsi/ufs/cdns-pltfrm.c |
2726 | @@ -99,6 +99,12 @@ static int cdns_ufs_link_startup_notify(struct ufs_hba *hba, |
2727 | */ |
2728 | ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0); |
2729 | |
2730 | + /* |
2731 | + * Disabling Autohibern8 feature in cadence UFS |
2732 | + * to mask unexpected interrupt trigger. |
2733 | + */ |
2734 | + hba->ahit = 0; |
2735 | + |
2736 | return 0; |
2737 | } |
2738 | |
2739 | diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c |
2740 | index f225eaa98ff8..d0f45600b669 100644 |
2741 | --- a/drivers/usb/core/hcd.c |
2742 | +++ b/drivers/usb/core/hcd.c |
2743 | @@ -1409,7 +1409,17 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, |
2744 | if (usb_endpoint_xfer_control(&urb->ep->desc)) { |
2745 | if (hcd->self.uses_pio_for_control) |
2746 | return ret; |
2747 | - if (hcd_uses_dma(hcd)) { |
2748 | + if (hcd->localmem_pool) { |
2749 | + ret = hcd_alloc_coherent( |
2750 | + urb->dev->bus, mem_flags, |
2751 | + &urb->setup_dma, |
2752 | + (void **)&urb->setup_packet, |
2753 | + sizeof(struct usb_ctrlrequest), |
2754 | + DMA_TO_DEVICE); |
2755 | + if (ret) |
2756 | + return ret; |
2757 | + urb->transfer_flags |= URB_SETUP_MAP_LOCAL; |
2758 | + } else if (hcd_uses_dma(hcd)) { |
2759 | if (is_vmalloc_addr(urb->setup_packet)) { |
2760 | WARN_ONCE(1, "setup packet is not dma capable\n"); |
2761 | return -EAGAIN; |
2762 | @@ -1427,23 +1437,22 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, |
2763 | urb->setup_dma)) |
2764 | return -EAGAIN; |
2765 | urb->transfer_flags |= URB_SETUP_MAP_SINGLE; |
2766 | - } else if (hcd->localmem_pool) { |
2767 | - ret = hcd_alloc_coherent( |
2768 | - urb->dev->bus, mem_flags, |
2769 | - &urb->setup_dma, |
2770 | - (void **)&urb->setup_packet, |
2771 | - sizeof(struct usb_ctrlrequest), |
2772 | - DMA_TO_DEVICE); |
2773 | - if (ret) |
2774 | - return ret; |
2775 | - urb->transfer_flags |= URB_SETUP_MAP_LOCAL; |
2776 | } |
2777 | } |
2778 | |
2779 | dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
2780 | if (urb->transfer_buffer_length != 0 |
2781 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { |
2782 | - if (hcd_uses_dma(hcd)) { |
2783 | + if (hcd->localmem_pool) { |
2784 | + ret = hcd_alloc_coherent( |
2785 | + urb->dev->bus, mem_flags, |
2786 | + &urb->transfer_dma, |
2787 | + &urb->transfer_buffer, |
2788 | + urb->transfer_buffer_length, |
2789 | + dir); |
2790 | + if (ret == 0) |
2791 | + urb->transfer_flags |= URB_MAP_LOCAL; |
2792 | + } else if (hcd_uses_dma(hcd)) { |
2793 | if (urb->num_sgs) { |
2794 | int n; |
2795 | |
2796 | @@ -1497,15 +1506,6 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, |
2797 | else |
2798 | urb->transfer_flags |= URB_DMA_MAP_SINGLE; |
2799 | } |
2800 | - } else if (hcd->localmem_pool) { |
2801 | - ret = hcd_alloc_coherent( |
2802 | - urb->dev->bus, mem_flags, |
2803 | - &urb->transfer_dma, |
2804 | - &urb->transfer_buffer, |
2805 | - urb->transfer_buffer_length, |
2806 | - dir); |
2807 | - if (ret == 0) |
2808 | - urb->transfer_flags |= URB_MAP_LOCAL; |
2809 | } |
2810 | if (ret && (urb->transfer_flags & (URB_SETUP_MAP_SINGLE | |
2811 | URB_SETUP_MAP_LOCAL))) |
2812 | diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c |
2813 | index 54a3c8195c96..2adcabe060c5 100644 |
2814 | --- a/drivers/usb/storage/scsiglue.c |
2815 | +++ b/drivers/usb/storage/scsiglue.c |
2816 | @@ -135,7 +135,8 @@ static int slave_configure(struct scsi_device *sdev) |
2817 | * For such controllers we need to make sure the block layer sets |
2818 | * up bounce buffers in addressable memory. |
2819 | */ |
2820 | - if (!hcd_uses_dma(bus_to_hcd(us->pusb_dev->bus))) |
2821 | + if (!hcd_uses_dma(bus_to_hcd(us->pusb_dev->bus)) || |
2822 | + (bus_to_hcd(us->pusb_dev->bus)->localmem_pool != NULL)) |
2823 | blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_HIGH); |
2824 | |
2825 | /* |
2826 | diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c |
2827 | index 3fa3f728fb39..2056f3f85f59 100644 |
2828 | --- a/drivers/vfio/pci/vfio_pci_intrs.c |
2829 | +++ b/drivers/vfio/pci/vfio_pci_intrs.c |
2830 | @@ -294,8 +294,8 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev, |
2831 | irq = pci_irq_vector(pdev, vector); |
2832 | |
2833 | if (vdev->ctx[vector].trigger) { |
2834 | - free_irq(irq, vdev->ctx[vector].trigger); |
2835 | irq_bypass_unregister_producer(&vdev->ctx[vector].producer); |
2836 | + free_irq(irq, vdev->ctx[vector].trigger); |
2837 | kfree(vdev->ctx[vector].name); |
2838 | eventfd_ctx_put(vdev->ctx[vector].trigger); |
2839 | vdev->ctx[vector].trigger = NULL; |
2840 | diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c |
2841 | index 0b4eee3bed66..efb2928ff6c8 100644 |
2842 | --- a/fs/cifs/cifs_debug.c |
2843 | +++ b/fs/cifs/cifs_debug.c |
2844 | @@ -256,6 +256,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) |
2845 | if (!server->rdma) |
2846 | goto skip_rdma; |
2847 | |
2848 | + if (!server->smbd_conn) { |
2849 | + seq_printf(m, "\nSMBDirect transport not available"); |
2850 | + goto skip_rdma; |
2851 | + } |
2852 | + |
2853 | seq_printf(m, "\nSMBDirect (in hex) protocol version: %x " |
2854 | "transport status: %x", |
2855 | server->smbd_conn->protocol, |
2856 | diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h |
2857 | index d78bfcc19156..5d2dd04b55a6 100644 |
2858 | --- a/fs/cifs/cifsglob.h |
2859 | +++ b/fs/cifs/cifsglob.h |
2860 | @@ -1524,6 +1524,7 @@ struct mid_q_entry { |
2861 | struct TCP_Server_Info *server; /* server corresponding to this mid */ |
2862 | __u64 mid; /* multiplex id */ |
2863 | __u16 credits; /* number of credits consumed by this mid */ |
2864 | + __u16 credits_received; /* number of credits from the response */ |
2865 | __u32 pid; /* process id */ |
2866 | __u32 sequence_number; /* for CIFS signing */ |
2867 | unsigned long when_alloc; /* when mid was created */ |
2868 | diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c |
2869 | index ccaa8bad336f..20c70cbab1ad 100644 |
2870 | --- a/fs/cifs/connect.c |
2871 | +++ b/fs/cifs/connect.c |
2872 | @@ -905,6 +905,20 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed) |
2873 | spin_unlock(&GlobalMid_Lock); |
2874 | } |
2875 | |
2876 | +static unsigned int |
2877 | +smb2_get_credits_from_hdr(char *buffer, struct TCP_Server_Info *server) |
2878 | +{ |
2879 | + struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer; |
2880 | + |
2881 | + /* |
2882 | + * SMB1 does not use credits. |
2883 | + */ |
2884 | + if (server->vals->header_preamble_size) |
2885 | + return 0; |
2886 | + |
2887 | + return le16_to_cpu(shdr->CreditRequest); |
2888 | +} |
2889 | + |
2890 | static void |
2891 | handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, |
2892 | char *buf, int malformed) |
2893 | @@ -912,6 +926,7 @@ handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, |
2894 | if (server->ops->check_trans2 && |
2895 | server->ops->check_trans2(mid, server, buf, malformed)) |
2896 | return; |
2897 | + mid->credits_received = smb2_get_credits_from_hdr(buf, server); |
2898 | mid->resp_buf = buf; |
2899 | mid->large_buf = server->large_buf; |
2900 | /* Was previous buf put in mpx struct for multi-rsp? */ |
2901 | @@ -1222,12 +1237,6 @@ next_pdu: |
2902 | for (i = 0; i < num_mids; i++) { |
2903 | if (mids[i] != NULL) { |
2904 | mids[i]->resp_buf_size = server->pdu_size; |
2905 | - if ((mids[i]->mid_flags & MID_WAIT_CANCELLED) && |
2906 | - mids[i]->mid_state == MID_RESPONSE_RECEIVED && |
2907 | - server->ops->handle_cancelled_mid) |
2908 | - server->ops->handle_cancelled_mid( |
2909 | - mids[i]->resp_buf, |
2910 | - server); |
2911 | |
2912 | if (!mids[i]->multiRsp || mids[i]->multiEnd) |
2913 | mids[i]->callback(mids[i]); |
2914 | @@ -4700,6 +4709,17 @@ static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, |
2915 | } |
2916 | |
2917 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2918 | +static inline void set_root_tcon(struct cifs_sb_info *cifs_sb, |
2919 | + struct cifs_tcon *tcon, |
2920 | + struct cifs_tcon **root) |
2921 | +{ |
2922 | + spin_lock(&cifs_tcp_ses_lock); |
2923 | + tcon->tc_count++; |
2924 | + tcon->remap = cifs_remap(cifs_sb); |
2925 | + spin_unlock(&cifs_tcp_ses_lock); |
2926 | + *root = tcon; |
2927 | +} |
2928 | + |
2929 | int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) |
2930 | { |
2931 | int rc = 0; |
2932 | @@ -4801,18 +4821,10 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) |
2933 | /* Cache out resolved root server */ |
2934 | (void)dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), |
2935 | root_path + 1, NULL, NULL); |
2936 | - /* |
2937 | - * Save root tcon for additional DFS requests to update or create a new |
2938 | - * DFS cache entry, or even perform DFS failover. |
2939 | - */ |
2940 | - spin_lock(&cifs_tcp_ses_lock); |
2941 | - tcon->tc_count++; |
2942 | - tcon->dfs_path = root_path; |
2943 | + kfree(root_path); |
2944 | root_path = NULL; |
2945 | - tcon->remap = cifs_remap(cifs_sb); |
2946 | - spin_unlock(&cifs_tcp_ses_lock); |
2947 | |
2948 | - root_tcon = tcon; |
2949 | + set_root_tcon(cifs_sb, tcon, &root_tcon); |
2950 | |
2951 | for (count = 1; ;) { |
2952 | if (!rc && tcon) { |
2953 | @@ -4849,6 +4861,15 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) |
2954 | mount_put_conns(cifs_sb, xid, server, ses, tcon); |
2955 | rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, |
2956 | &tcon); |
2957 | + /* |
2958 | + * Ensure that DFS referrals go through new root server. |
2959 | + */ |
2960 | + if (!rc && tcon && |
2961 | + (tcon->share_flags & (SHI1005_FLAGS_DFS | |
2962 | + SHI1005_FLAGS_DFS_ROOT))) { |
2963 | + cifs_put_tcon(root_tcon); |
2964 | + set_root_tcon(cifs_sb, tcon, &root_tcon); |
2965 | + } |
2966 | } |
2967 | if (rc) { |
2968 | if (rc == -EACCES || rc == -EOPNOTSUPP) |
2969 | diff --git a/fs/cifs/file.c b/fs/cifs/file.c |
2970 | index a3b6be80f8a9..c32650f14c9b 100644 |
2971 | --- a/fs/cifs/file.c |
2972 | +++ b/fs/cifs/file.c |
2973 | @@ -729,6 +729,13 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) |
2974 | if (backup_cred(cifs_sb)) |
2975 | create_options |= CREATE_OPEN_BACKUP_INTENT; |
2976 | |
2977 | + /* O_SYNC also has bit for O_DSYNC so following check picks up either */ |
2978 | + if (cfile->f_flags & O_SYNC) |
2979 | + create_options |= CREATE_WRITE_THROUGH; |
2980 | + |
2981 | + if (cfile->f_flags & O_DIRECT) |
2982 | + create_options |= CREATE_NO_BUFFER; |
2983 | + |
2984 | if (server->ops->get_lease_key) |
2985 | server->ops->get_lease_key(inode, &cfile->fid); |
2986 | |
2987 | diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c |
2988 | index 449d1584ff72..766974fe637a 100644 |
2989 | --- a/fs/cifs/smb2misc.c |
2990 | +++ b/fs/cifs/smb2misc.c |
2991 | @@ -743,36 +743,67 @@ smb2_cancelled_close_fid(struct work_struct *work) |
2992 | kfree(cancelled); |
2993 | } |
2994 | |
2995 | +/* Caller should already has an extra reference to @tcon */ |
2996 | +static int |
2997 | +__smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid, |
2998 | + __u64 volatile_fid) |
2999 | +{ |
3000 | + struct close_cancelled_open *cancelled; |
3001 | + |
3002 | + cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); |
3003 | + if (!cancelled) |
3004 | + return -ENOMEM; |
3005 | + |
3006 | + cancelled->fid.persistent_fid = persistent_fid; |
3007 | + cancelled->fid.volatile_fid = volatile_fid; |
3008 | + cancelled->tcon = tcon; |
3009 | + INIT_WORK(&cancelled->work, smb2_cancelled_close_fid); |
3010 | + WARN_ON(queue_work(cifsiod_wq, &cancelled->work) == false); |
3011 | + |
3012 | + return 0; |
3013 | +} |
3014 | + |
3015 | +int |
3016 | +smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid, |
3017 | + __u64 volatile_fid) |
3018 | +{ |
3019 | + int rc; |
3020 | + |
3021 | + cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count); |
3022 | + spin_lock(&cifs_tcp_ses_lock); |
3023 | + tcon->tc_count++; |
3024 | + spin_unlock(&cifs_tcp_ses_lock); |
3025 | + |
3026 | + rc = __smb2_handle_cancelled_close(tcon, persistent_fid, volatile_fid); |
3027 | + if (rc) |
3028 | + cifs_put_tcon(tcon); |
3029 | + |
3030 | + return rc; |
3031 | +} |
3032 | + |
3033 | int |
3034 | smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) |
3035 | { |
3036 | struct smb2_sync_hdr *sync_hdr = (struct smb2_sync_hdr *)buffer; |
3037 | struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer; |
3038 | struct cifs_tcon *tcon; |
3039 | - struct close_cancelled_open *cancelled; |
3040 | + int rc; |
3041 | |
3042 | if (sync_hdr->Command != SMB2_CREATE || |
3043 | sync_hdr->Status != STATUS_SUCCESS) |
3044 | return 0; |
3045 | |
3046 | - cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); |
3047 | - if (!cancelled) |
3048 | - return -ENOMEM; |
3049 | - |
3050 | tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId, |
3051 | sync_hdr->TreeId); |
3052 | - if (!tcon) { |
3053 | - kfree(cancelled); |
3054 | + if (!tcon) |
3055 | return -ENOENT; |
3056 | - } |
3057 | |
3058 | - cancelled->fid.persistent_fid = rsp->PersistentFileId; |
3059 | - cancelled->fid.volatile_fid = rsp->VolatileFileId; |
3060 | - cancelled->tcon = tcon; |
3061 | - INIT_WORK(&cancelled->work, smb2_cancelled_close_fid); |
3062 | - queue_work(cifsiod_wq, &cancelled->work); |
3063 | + rc = __smb2_handle_cancelled_close(tcon, rsp->PersistentFileId, |
3064 | + rsp->VolatileFileId); |
3065 | + if (rc) |
3066 | + cifs_put_tcon(tcon); |
3067 | |
3068 | - return 0; |
3069 | + return rc; |
3070 | } |
3071 | |
3072 | /** |
3073 | diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c |
3074 | index cd55af9b7cc5..b5c1cba3e6a1 100644 |
3075 | --- a/fs/cifs/smb2ops.c |
3076 | +++ b/fs/cifs/smb2ops.c |
3077 | @@ -151,13 +151,7 @@ smb2_get_credits_field(struct TCP_Server_Info *server, const int optype) |
3078 | static unsigned int |
3079 | smb2_get_credits(struct mid_q_entry *mid) |
3080 | { |
3081 | - struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)mid->resp_buf; |
3082 | - |
3083 | - if (mid->mid_state == MID_RESPONSE_RECEIVED |
3084 | - || mid->mid_state == MID_RESPONSE_MALFORMED) |
3085 | - return le16_to_cpu(shdr->CreditRequest); |
3086 | - |
3087 | - return 0; |
3088 | + return mid->credits_received; |
3089 | } |
3090 | |
3091 | static int |
3092 | diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c |
3093 | index 05149862aea4..c985caa2d955 100644 |
3094 | --- a/fs/cifs/smb2pdu.c |
3095 | +++ b/fs/cifs/smb2pdu.c |
3096 | @@ -2972,7 +2972,21 @@ int |
3097 | SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, |
3098 | u64 persistent_fid, u64 volatile_fid) |
3099 | { |
3100 | - return SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0); |
3101 | + int rc; |
3102 | + int tmp_rc; |
3103 | + |
3104 | + rc = SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0); |
3105 | + |
3106 | + /* retry close in a worker thread if this one is interrupted */ |
3107 | + if (rc == -EINTR) { |
3108 | + tmp_rc = smb2_handle_cancelled_close(tcon, persistent_fid, |
3109 | + volatile_fid); |
3110 | + if (tmp_rc) |
3111 | + cifs_dbg(VFS, "handle cancelled close fid 0x%llx returned error %d\n", |
3112 | + persistent_fid, tmp_rc); |
3113 | + } |
3114 | + |
3115 | + return rc; |
3116 | } |
3117 | |
3118 | int |
3119 | diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h |
3120 | index 71b2930b8e0b..2a12a2fa38a2 100644 |
3121 | --- a/fs/cifs/smb2proto.h |
3122 | +++ b/fs/cifs/smb2proto.h |
3123 | @@ -212,6 +212,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, |
3124 | extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, |
3125 | const u64 persistent_fid, const u64 volatile_fid, |
3126 | const __u8 oplock_level); |
3127 | +extern int smb2_handle_cancelled_close(struct cifs_tcon *tcon, |
3128 | + __u64 persistent_fid, |
3129 | + __u64 volatile_fid); |
3130 | extern int smb2_handle_cancelled_mid(char *buffer, |
3131 | struct TCP_Server_Info *server); |
3132 | void smb2_cancelled_close_fid(struct work_struct *work); |
3133 | diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c |
3134 | index 3c91fa97c9a8..5b1b97e9e0c9 100644 |
3135 | --- a/fs/cifs/smbdirect.c |
3136 | +++ b/fs/cifs/smbdirect.c |
3137 | @@ -1069,7 +1069,7 @@ static int smbd_post_send_data( |
3138 | |
3139 | if (n_vec > SMBDIRECT_MAX_SGE) { |
3140 | cifs_dbg(VFS, "Can't fit data to SGL, n_vec=%d\n", n_vec); |
3141 | - return -ENOMEM; |
3142 | + return -EINVAL; |
3143 | } |
3144 | |
3145 | sg_init_table(sgl, n_vec); |
3146 | @@ -1476,6 +1476,7 @@ void smbd_destroy(struct TCP_Server_Info *server) |
3147 | info->transport_status = SMBD_DESTROYED; |
3148 | |
3149 | destroy_workqueue(info->workqueue); |
3150 | + log_rdma_event(INFO, "rdma session destroyed\n"); |
3151 | kfree(info); |
3152 | } |
3153 | |
3154 | @@ -1505,8 +1506,9 @@ create_conn: |
3155 | log_rdma_event(INFO, "creating rdma session\n"); |
3156 | server->smbd_conn = smbd_get_connection( |
3157 | server, (struct sockaddr *) &server->dstaddr); |
3158 | - log_rdma_event(INFO, "created rdma session info=%p\n", |
3159 | - server->smbd_conn); |
3160 | + |
3161 | + if (server->smbd_conn) |
3162 | + cifs_dbg(VFS, "RDMA transport re-established\n"); |
3163 | |
3164 | return server->smbd_conn ? 0 : -ENOENT; |
3165 | } |
3166 | @@ -1970,7 +1972,7 @@ read_rfc1002_done: |
3167 | |
3168 | if (info->transport_status != SMBD_CONNECTED) { |
3169 | log_read(ERR, "disconnected\n"); |
3170 | - return 0; |
3171 | + return -ECONNABORTED; |
3172 | } |
3173 | |
3174 | goto again; |
3175 | @@ -2269,12 +2271,7 @@ static void smbd_mr_recovery_work(struct work_struct *work) |
3176 | int rc; |
3177 | |
3178 | list_for_each_entry(smbdirect_mr, &info->mr_list, list) { |
3179 | - if (smbdirect_mr->state == MR_INVALIDATED) |
3180 | - ib_dma_unmap_sg( |
3181 | - info->id->device, smbdirect_mr->sgl, |
3182 | - smbdirect_mr->sgl_count, |
3183 | - smbdirect_mr->dir); |
3184 | - else if (smbdirect_mr->state == MR_ERROR) { |
3185 | + if (smbdirect_mr->state == MR_ERROR) { |
3186 | |
3187 | /* recover this MR entry */ |
3188 | rc = ib_dereg_mr(smbdirect_mr->mr); |
3189 | @@ -2602,11 +2599,20 @@ int smbd_deregister_mr(struct smbd_mr *smbdirect_mr) |
3190 | */ |
3191 | smbdirect_mr->state = MR_INVALIDATED; |
3192 | |
3193 | - /* |
3194 | - * Schedule the work to do MR recovery for future I/Os |
3195 | - * MR recovery is slow and we don't want it to block the current I/O |
3196 | - */ |
3197 | - queue_work(info->workqueue, &info->mr_recovery_work); |
3198 | + if (smbdirect_mr->state == MR_INVALIDATED) { |
3199 | + ib_dma_unmap_sg( |
3200 | + info->id->device, smbdirect_mr->sgl, |
3201 | + smbdirect_mr->sgl_count, |
3202 | + smbdirect_mr->dir); |
3203 | + smbdirect_mr->state = MR_READY; |
3204 | + if (atomic_inc_return(&info->mr_ready_count) == 1) |
3205 | + wake_up_interruptible(&info->wait_mr); |
3206 | + } else |
3207 | + /* |
3208 | + * Schedule the work to do MR recovery for future I/Os MR |
3209 | + * recovery is slow and don't want it to block current I/O |
3210 | + */ |
3211 | + queue_work(info->workqueue, &info->mr_recovery_work); |
3212 | |
3213 | done: |
3214 | if (atomic_dec_and_test(&info->mr_used_count)) |
3215 | diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c |
3216 | index ca3de62688d6..755434d5e4e7 100644 |
3217 | --- a/fs/cifs/transport.c |
3218 | +++ b/fs/cifs/transport.c |
3219 | @@ -93,8 +93,14 @@ static void _cifs_mid_q_entry_release(struct kref *refcount) |
3220 | __u16 smb_cmd = le16_to_cpu(midEntry->command); |
3221 | unsigned long now; |
3222 | unsigned long roundtrip_time; |
3223 | - struct TCP_Server_Info *server = midEntry->server; |
3224 | #endif |
3225 | + struct TCP_Server_Info *server = midEntry->server; |
3226 | + |
3227 | + if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && |
3228 | + midEntry->mid_state == MID_RESPONSE_RECEIVED && |
3229 | + server->ops->handle_cancelled_mid) |
3230 | + server->ops->handle_cancelled_mid(midEntry->resp_buf, server); |
3231 | + |
3232 | midEntry->mid_state = MID_FREE; |
3233 | atomic_dec(&midCount); |
3234 | if (midEntry->large_buf) |
3235 | @@ -319,8 +325,11 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, |
3236 | int val = 1; |
3237 | __be32 rfc1002_marker; |
3238 | |
3239 | - if (cifs_rdma_enabled(server) && server->smbd_conn) { |
3240 | - rc = smbd_send(server, num_rqst, rqst); |
3241 | + if (cifs_rdma_enabled(server)) { |
3242 | + /* return -EAGAIN when connecting or reconnecting */ |
3243 | + rc = -EAGAIN; |
3244 | + if (server->smbd_conn) |
3245 | + rc = smbd_send(server, num_rqst, rqst); |
3246 | goto smbd_done; |
3247 | } |
3248 | |
3249 | @@ -1119,8 +1128,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, |
3250 | midQ[i]->mid, le16_to_cpu(midQ[i]->command)); |
3251 | send_cancel(server, &rqst[i], midQ[i]); |
3252 | spin_lock(&GlobalMid_Lock); |
3253 | + midQ[i]->mid_flags |= MID_WAIT_CANCELLED; |
3254 | if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { |
3255 | - midQ[i]->mid_flags |= MID_WAIT_CANCELLED; |
3256 | midQ[i]->callback = cifs_cancelled_callback; |
3257 | cancelled_mid[i] = true; |
3258 | credits[i].value = 0; |
3259 | diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c |
3260 | index 997b326247e2..c53e3b892210 100644 |
3261 | --- a/fs/gfs2/file.c |
3262 | +++ b/fs/gfs2/file.c |
3263 | @@ -381,27 +381,28 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) |
3264 | /** |
3265 | * gfs2_allocate_page_backing - Allocate blocks for a write fault |
3266 | * @page: The (locked) page to allocate backing for |
3267 | + * @length: Size of the allocation |
3268 | * |
3269 | * We try to allocate all the blocks required for the page in one go. This |
3270 | * might fail for various reasons, so we keep trying until all the blocks to |
3271 | * back this page are allocated. If some of the blocks are already allocated, |
3272 | * that is ok too. |
3273 | */ |
3274 | -static int gfs2_allocate_page_backing(struct page *page) |
3275 | +static int gfs2_allocate_page_backing(struct page *page, unsigned int length) |
3276 | { |
3277 | u64 pos = page_offset(page); |
3278 | - u64 size = PAGE_SIZE; |
3279 | |
3280 | do { |
3281 | struct iomap iomap = { }; |
3282 | |
3283 | - if (gfs2_iomap_get_alloc(page->mapping->host, pos, 1, &iomap)) |
3284 | + if (gfs2_iomap_get_alloc(page->mapping->host, pos, length, &iomap)) |
3285 | return -EIO; |
3286 | |
3287 | - iomap.length = min(iomap.length, size); |
3288 | - size -= iomap.length; |
3289 | + if (length < iomap.length) |
3290 | + iomap.length = length; |
3291 | + length -= iomap.length; |
3292 | pos += iomap.length; |
3293 | - } while (size > 0); |
3294 | + } while (length > 0); |
3295 | |
3296 | return 0; |
3297 | } |
3298 | @@ -501,7 +502,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf) |
3299 | if (gfs2_is_stuffed(ip)) |
3300 | ret = gfs2_unstuff_dinode(ip, page); |
3301 | if (ret == 0) |
3302 | - ret = gfs2_allocate_page_backing(page); |
3303 | + ret = gfs2_allocate_page_backing(page, PAGE_SIZE); |
3304 | |
3305 | out_trans_end: |
3306 | if (ret) |
3307 | diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c |
3308 | index 58e237fba565..2aed73666a65 100644 |
3309 | --- a/fs/gfs2/log.c |
3310 | +++ b/fs/gfs2/log.c |
3311 | @@ -609,6 +609,14 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) |
3312 | list_add(&bd->bd_list, &sdp->sd_log_revokes); |
3313 | } |
3314 | |
3315 | +void gfs2_glock_remove_revoke(struct gfs2_glock *gl) |
3316 | +{ |
3317 | + if (atomic_dec_return(&gl->gl_revokes) == 0) { |
3318 | + clear_bit(GLF_LFLUSH, &gl->gl_flags); |
3319 | + gfs2_glock_queue_put(gl); |
3320 | + } |
3321 | +} |
3322 | + |
3323 | void gfs2_write_revokes(struct gfs2_sbd *sdp) |
3324 | { |
3325 | struct gfs2_trans *tr; |
3326 | diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h |
3327 | index 2315fca47a2b..c762da494546 100644 |
3328 | --- a/fs/gfs2/log.h |
3329 | +++ b/fs/gfs2/log.h |
3330 | @@ -77,6 +77,7 @@ extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc) |
3331 | extern void gfs2_log_shutdown(struct gfs2_sbd *sdp); |
3332 | extern int gfs2_logd(void *data); |
3333 | extern void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); |
3334 | +extern void gfs2_glock_remove_revoke(struct gfs2_glock *gl); |
3335 | extern void gfs2_write_revokes(struct gfs2_sbd *sdp); |
3336 | |
3337 | #endif /* __LOG_DOT_H__ */ |
3338 | diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c |
3339 | index 5b17979af539..e2437b775456 100644 |
3340 | --- a/fs/gfs2/lops.c |
3341 | +++ b/fs/gfs2/lops.c |
3342 | @@ -882,10 +882,7 @@ static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
3343 | bd = list_entry(head->next, struct gfs2_bufdata, bd_list); |
3344 | list_del_init(&bd->bd_list); |
3345 | gl = bd->bd_gl; |
3346 | - if (atomic_dec_return(&gl->gl_revokes) == 0) { |
3347 | - clear_bit(GLF_LFLUSH, &gl->gl_flags); |
3348 | - gfs2_glock_queue_put(gl); |
3349 | - } |
3350 | + gfs2_glock_remove_revoke(gl); |
3351 | kmem_cache_free(gfs2_bufdata_cachep, bd); |
3352 | } |
3353 | } |
3354 | diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c |
3355 | index 35e3059255fe..9d4227330de4 100644 |
3356 | --- a/fs/gfs2/trans.c |
3357 | +++ b/fs/gfs2/trans.c |
3358 | @@ -262,6 +262,8 @@ void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len) |
3359 | list_del_init(&bd->bd_list); |
3360 | gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke); |
3361 | sdp->sd_log_num_revoke--; |
3362 | + if (bd->bd_gl) |
3363 | + gfs2_glock_remove_revoke(bd->bd_gl); |
3364 | kmem_cache_free(gfs2_bufdata_cachep, bd); |
3365 | tr->tr_num_revoke--; |
3366 | if (--n == 0) |
3367 | diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h |
3368 | index 9b6336ad3266..e459b38ef33c 100644 |
3369 | --- a/include/linux/mmc/card.h |
3370 | +++ b/include/linux/mmc/card.h |
3371 | @@ -291,6 +291,7 @@ struct mmc_card { |
3372 | struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ |
3373 | |
3374 | unsigned int sdio_funcs; /* number of SDIO functions */ |
3375 | + atomic_t sdio_funcs_probed; /* number of probed SDIO funcs */ |
3376 | struct sdio_cccr cccr; /* common card info */ |
3377 | struct sdio_cis cis; /* common tuple info */ |
3378 | struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */ |
3379 | diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h |
3380 | index ebf5ef17cc2a..24a6263c9931 100644 |
3381 | --- a/include/linux/pm_qos.h |
3382 | +++ b/include/linux/pm_qos.h |
3383 | @@ -256,7 +256,7 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev) |
3384 | #endif |
3385 | |
3386 | #define FREQ_QOS_MIN_DEFAULT_VALUE 0 |
3387 | -#define FREQ_QOS_MAX_DEFAULT_VALUE (-1) |
3388 | +#define FREQ_QOS_MAX_DEFAULT_VALUE S32_MAX |
3389 | |
3390 | enum freq_qos_req_type { |
3391 | FREQ_QOS_MIN = 1, |
3392 | diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c |
3393 | index f9707fb05efe..682ed39f79b0 100644 |
3394 | --- a/sound/hda/hdac_stream.c |
3395 | +++ b/sound/hda/hdac_stream.c |
3396 | @@ -120,10 +120,8 @@ void snd_hdac_stream_clear(struct hdac_stream *azx_dev) |
3397 | snd_hdac_stream_updateb(azx_dev, SD_CTL, |
3398 | SD_CTL_DMA_START | SD_INT_MASK, 0); |
3399 | snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */ |
3400 | - if (azx_dev->stripe) { |
3401 | + if (azx_dev->stripe) |
3402 | snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0); |
3403 | - azx_dev->stripe = 0; |
3404 | - } |
3405 | azx_dev->running = false; |
3406 | } |
3407 | EXPORT_SYMBOL_GPL(snd_hdac_stream_clear); |
3408 | diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c |
3409 | index 4dafc864d765..488c17c9f375 100644 |
3410 | --- a/sound/pci/hda/patch_hdmi.c |
3411 | +++ b/sound/pci/hda/patch_hdmi.c |
3412 | @@ -1983,6 +1983,8 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, |
3413 | per_cvt->assigned = 0; |
3414 | hinfo->nid = 0; |
3415 | |
3416 | + azx_stream(get_azx_dev(substream))->stripe = 0; |
3417 | + |
3418 | mutex_lock(&spec->pcm_lock); |
3419 | snd_hda_spdif_ctls_unassign(codec, pcm_idx); |
3420 | clear_bit(pcm_idx, &spec->pcm_in_use); |