Commit 7f98b894 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

media: atomisp: fix a slab error due to a wrong free

The mmu mapping logic uses a different logic depending on the
RAM size: if it is lower than 2GB, it uses kmem_cache_zalloc(),
but if memory is bigger than that, it uses its own way to
allocate memory.

Yet, when freeing, it uses kmem_cache_free() for any cases.

On recent Kernels, slab tracks the memory allocated on it,
with causes those warnings:

 virt_to_cache: Object is not a Slab page!
 WARNING: CPU: 0 PID: 758 at mm/slab.h:475 cache_from_obj+0xab/0xf0
 Modules linked in: snd_soc_sst_cht_bsw_rt5645(E) mei_hdcp(E) gpio_keys(E) intel_rapl_msr(E) intel_powerclamp(E) coretemp(E) kvm_intel(E) kvm(E) irqbypass(E) crct10dif_pclmul(E) crc32_pclmul(E) ghash_clmulni_intel(E) atomisp_ov2680(CE) intel_cstate(E) asus_nb_wmi(E) wdat_wdt(E) pcspkr(E) ath10k_pci(E) ath10k_core(E) intel_chtdc_ti_pwrbtn(E) ath(E) mac80211(E) btusb(E) joydev(E) btrtl(E) btbcm(E) btintel(E) bluetooth(E) libarc4(E) ecdh_generic(E) cfg80211(E) ecc(E) hid_sensor_gyro_3d(E) hid_sensor_accel_3d(E) hid_sensor_trigger(E) hid_sensor_iio_common(E) industrialio_triggered_buffer(E) kfifo_buf(E) industrialio(E) atomisp(CE) videobuf_vmalloc(E) videobuf_core(E) videodev(E) mc(E) snd_soc_rt5645(E) snd_soc_rl6231(E) snd_intel_sst_acpi(E) snd_intel_sst_core(E) snd_soc_sst_atom_hifi2_platform(E) snd_soc_acpi_intel_match(E) intel_hid(E) spi_pxa2xx_platform(E) snd_soc_acpi(E) snd_soc_core(E) snd_compress(E) dw_dmac(E) intel_xhci_usb_role_switch(E) int3406_thermal(E)
  snd_hdmi_lpe_audio(E) int3403_thermal(E) int3400_thermal(E) acpi_thermal_rel(E) snd_seq(E) intel_int0002_vgpio(E) soc_button_array(E) snd_seq_device(E) acpi_pad(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) lpc_ich(E) mei_txe(E) mei(E) processor_thermal_device(E) intel_soc_dts_iosf(E) intel_rapl_common(E) int340x_thermal_zone(E) ip_tables(E) hid_sensor_hub(E) intel_ishtp_loader(E) intel_ishtp_hid(E) mmc_block(E) hid_multitouch(E) crc32c_intel(E) i915(E) i2c_algo_bit(E) drm_kms_helper(E) hid_asus(E) asus_wmi(E) sparse_keymap(E) rfkill(E) drm(E) intel_ish_ipc(E) intel_ishtp(E) wmi(E) video(E) i2c_hid(E) sdhci_acpi(E) sdhci(E) mmc_core(E) pwm_lpss_platform(E) pwm_lpss(E) fuse(E)
 CPU: 0 PID: 758 Comm: v4l_id Tainted: G         C  E     5.7.0-rc2+ #40
 Hardware name: ASUSTeK COMPUTER INC. T101HA/T101HA, BIOS T101HA.306 04/23/2019
 RIP: 0010:cache_from_obj+0xab/0xf0
 Code: c3 31 c0 80 3d 1c 38 72 01 00 75 f0 48 c7 c6 20 12 06 b5 48 c7 c7 10 f3 37 b5 48 89 04 24 c6 05 01 38 72 01 01 e8 2c 99 e0 ff <0f> 0b 48 8b 04 24 eb ca 48 8b 57 58 48 8b 48 58 48 c7 c6 30 12 06
 RSP: 0018:ffffb0a4c07cfb10 EFLAGS: 00010282
 RAX: 0000000000000029 RBX: 0000000000000048 RCX: 0000000000000000
 RDX: ffffa004fbca5b80 RSI: ffffa004fbc19cc8 RDI: ffffa004fbc19cc8
 RBP: 0000000000c49000 R08: 00000000000004f7 R09: 0000000000000001
 R10: 0000000000aaaaaa R11: ffffffffb50e0600 R12: ffffffffc0be0a00
 R13: ffffa003f2448000 R14: 0000000000c49000 R15: ffffa003f2448000
 FS:  00007f9060c9cb80(0000) GS:ffffa004fbc00000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 0000559fc55b8000 CR3: 0000000165b02000 CR4: 00000000001006f0
 Call Trace:
  kmem_cache_free+0x19/0x180
  mmu_l2_unmap+0xd1/0x100 [atomisp]
  mmu_unmap+0xd0/0xf0 [atomisp]
  hmm_bo_unbind+0x62/0xb0 [atomisp]
  hmm_free+0x44/0x60 [atomisp]
  ia_css_spctrl_unload_fw+0x30/0x50 [atomisp]
  ia_css_uninit+0x3a/0x90 [atomisp]
  atomisp_open+0x50b/0x5c0 [atomisp]
  v4l2_open+0x85/0xf0 [videodev]
  chrdev_open+0xdd/0x210
  ? cdev_device_add+0xc0/0xc0
  do_dentry_open+0x13a/0x380
  path_openat+0xa9a/0xfe0
  do_filp_open+0x75/0x100
  ? __check_object_size+0x12e/0x13c
  ? __alloc_fd+0x44/0x150
  do_sys_openat2+0x8a/0x130
  __x64_sys_openat+0x46/0x70
  do_syscall_64+0x5b/0xf0
  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Solve it by calling free_page() directly
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 5f1e9dd5
...@@ -142,7 +142,10 @@ static void free_page_table(struct isp_mmu *mmu, phys_addr_t page) ...@@ -142,7 +142,10 @@ static void free_page_table(struct isp_mmu *mmu, phys_addr_t page)
set_memory_wb((unsigned long)virt, 1); set_memory_wb((unsigned long)virt, 1);
#endif #endif
kmem_cache_free(mmu->tbl_cache, virt); if (totalram_pages() > (unsigned long)NR_PAGES_2GB)
free_page((unsigned long)virt);
else
kmem_cache_free(mmu->tbl_cache, virt);
} }
static void mmu_remap_error(struct isp_mmu *mmu, static void mmu_remap_error(struct isp_mmu *mmu,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment