Merge d133023c9a ("ocfs2: stop quota recovery before disabling quotas") into android16-6.12-lts
Steps on the way to 6.12.29 Change-Id: I52c3962ac2f0f7a3de8001ebcc8e66628283d9fb Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -111,7 +111,14 @@ static struct arm64_cpu_capabilities const __ro_after_init *cpucap_ptrs[ARM64_NC
|
||||
|
||||
DECLARE_BITMAP(boot_cpucaps, ARM64_NCAPS);
|
||||
|
||||
bool arm64_use_ng_mappings = false;
|
||||
/*
|
||||
* arm64_use_ng_mappings must be placed in the .data section, otherwise it
|
||||
* ends up in the .bss section where it is initialized in early_map_kernel()
|
||||
* after the MMU (with the idmap) was enabled. create_init_idmap() - which
|
||||
* runs before early_map_kernel() and reads the variable via PTE_MAYBE_NG -
|
||||
* may end up generating an incorrect idmap page table attributes.
|
||||
*/
|
||||
bool arm64_use_ng_mappings __read_mostly = false;
|
||||
EXPORT_SYMBOL(arm64_use_ng_mappings);
|
||||
|
||||
DEFINE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector) = vectors;
|
||||
|
||||
@@ -17,10 +17,12 @@ struct ucode_cpu_info {
|
||||
void load_ucode_bsp(void);
|
||||
void load_ucode_ap(void);
|
||||
void microcode_bsp_resume(void);
|
||||
bool __init microcode_loader_disabled(void);
|
||||
#else
|
||||
static inline void load_ucode_bsp(void) { }
|
||||
static inline void load_ucode_ap(void) { }
|
||||
static inline void microcode_bsp_resume(void) { }
|
||||
static inline bool __init microcode_loader_disabled(void) { return false; }
|
||||
#endif
|
||||
|
||||
extern unsigned long initrd_start_early;
|
||||
|
||||
@@ -1099,15 +1099,17 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz
|
||||
|
||||
static int __init save_microcode_in_initrd(void)
|
||||
{
|
||||
unsigned int cpuid_1_eax = native_cpuid_eax(1);
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
struct cont_desc desc = { 0 };
|
||||
unsigned int cpuid_1_eax;
|
||||
enum ucode_state ret;
|
||||
struct cpio_data cp;
|
||||
|
||||
if (dis_ucode_ldr || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10)
|
||||
if (microcode_loader_disabled() || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10)
|
||||
return 0;
|
||||
|
||||
cpuid_1_eax = native_cpuid_eax(1);
|
||||
|
||||
if (!find_blobs_in_containers(&cp))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
static struct microcode_ops *microcode_ops;
|
||||
bool dis_ucode_ldr = true;
|
||||
static struct microcode_ops *microcode_ops;
|
||||
static bool dis_ucode_ldr = false;
|
||||
|
||||
bool force_minrev = IS_ENABLED(CONFIG_MICROCODE_LATE_FORCE_MINREV);
|
||||
module_param(force_minrev, bool, S_IRUSR | S_IWUSR);
|
||||
@@ -84,6 +84,9 @@ static bool amd_check_current_patch_level(void)
|
||||
u32 lvl, dummy, i;
|
||||
u32 *levels;
|
||||
|
||||
if (x86_cpuid_vendor() != X86_VENDOR_AMD)
|
||||
return false;
|
||||
|
||||
native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
|
||||
|
||||
levels = final_levels;
|
||||
@@ -95,27 +98,29 @@ static bool amd_check_current_patch_level(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool __init check_loader_disabled_bsp(void)
|
||||
bool __init microcode_loader_disabled(void)
|
||||
{
|
||||
static const char *__dis_opt_str = "dis_ucode_ldr";
|
||||
const char *cmdline = boot_command_line;
|
||||
const char *option = __dis_opt_str;
|
||||
|
||||
/*
|
||||
* CPUID(1).ECX[31]: reserved for hypervisor use. This is still not
|
||||
* completely accurate as xen pv guests don't see that CPUID bit set but
|
||||
* that's good enough as they don't land on the BSP path anyway.
|
||||
*/
|
||||
if (native_cpuid_ecx(1) & BIT(31))
|
||||
if (dis_ucode_ldr)
|
||||
return true;
|
||||
|
||||
if (x86_cpuid_vendor() == X86_VENDOR_AMD) {
|
||||
if (amd_check_current_patch_level())
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cmdline_find_option_bool(cmdline, option) <= 0)
|
||||
dis_ucode_ldr = false;
|
||||
/*
|
||||
* Disable when:
|
||||
*
|
||||
* 1) The CPU does not support CPUID.
|
||||
*
|
||||
* 2) Bit 31 in CPUID[1]:ECX is clear
|
||||
* The bit is reserved for hypervisor use. This is still not
|
||||
* completely accurate as XEN PV guests don't see that CPUID bit
|
||||
* set, but that's good enough as they don't land on the BSP
|
||||
* path anyway.
|
||||
*
|
||||
* 3) Certain AMD patch levels are not allowed to be
|
||||
* overwritten.
|
||||
*/
|
||||
if (!have_cpuid_p() ||
|
||||
native_cpuid_ecx(1) & BIT(31) ||
|
||||
amd_check_current_patch_level())
|
||||
dis_ucode_ldr = true;
|
||||
|
||||
return dis_ucode_ldr;
|
||||
}
|
||||
@@ -125,7 +130,10 @@ void __init load_ucode_bsp(void)
|
||||
unsigned int cpuid_1_eax;
|
||||
bool intel = true;
|
||||
|
||||
if (!have_cpuid_p())
|
||||
if (cmdline_find_option_bool(boot_command_line, "dis_ucode_ldr") > 0)
|
||||
dis_ucode_ldr = true;
|
||||
|
||||
if (microcode_loader_disabled())
|
||||
return;
|
||||
|
||||
cpuid_1_eax = native_cpuid_eax(1);
|
||||
@@ -146,9 +154,6 @@ void __init load_ucode_bsp(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (check_loader_disabled_bsp())
|
||||
return;
|
||||
|
||||
if (intel)
|
||||
load_ucode_intel_bsp(&early_data);
|
||||
else
|
||||
@@ -159,6 +164,11 @@ void load_ucode_ap(void)
|
||||
{
|
||||
unsigned int cpuid_1_eax;
|
||||
|
||||
/*
|
||||
* Can't use microcode_loader_disabled() here - .init section
|
||||
* hell. It doesn't have to either - the BSP variant must've
|
||||
* parsed cmdline already anyway.
|
||||
*/
|
||||
if (dis_ucode_ldr)
|
||||
return;
|
||||
|
||||
@@ -810,7 +820,7 @@ static int __init microcode_init(void)
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
int error;
|
||||
|
||||
if (dis_ucode_ldr)
|
||||
if (microcode_loader_disabled())
|
||||
return -EINVAL;
|
||||
|
||||
if (c->x86_vendor == X86_VENDOR_INTEL)
|
||||
|
||||
@@ -395,7 +395,7 @@ static int __init save_builtin_microcode(void)
|
||||
if (xchg(&ucode_patch_va, NULL) != UCODE_BSP_LOADED)
|
||||
return 0;
|
||||
|
||||
if (dis_ucode_ldr || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
|
||||
if (microcode_loader_disabled() || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
|
||||
return 0;
|
||||
|
||||
uci.mc = get_microcode_blob(&uci, true);
|
||||
|
||||
@@ -94,7 +94,6 @@ static inline unsigned int x86_cpuid_family(void)
|
||||
return x86_family(eax);
|
||||
}
|
||||
|
||||
extern bool dis_ucode_ldr;
|
||||
extern bool force_minrev;
|
||||
|
||||
#ifdef CONFIG_CPU_SUP_AMD
|
||||
|
||||
@@ -145,10 +145,6 @@ void __init __no_stack_protector mk_early_pgtbl_32(void)
|
||||
*ptr = (unsigned long)ptep + PAGE_OFFSET;
|
||||
|
||||
#ifdef CONFIG_MICROCODE_INITRD32
|
||||
/* Running on a hypervisor? */
|
||||
if (native_cpuid_ecx(1) & BIT(31))
|
||||
return;
|
||||
|
||||
params = (struct boot_params *)__pa_nodebug(&boot_params);
|
||||
if (!params->hdr.ramdisk_size || !params->hdr.ramdisk_image)
|
||||
return;
|
||||
|
||||
@@ -131,6 +131,7 @@ void kvm_smm_changed(struct kvm_vcpu *vcpu, bool entering_smm)
|
||||
|
||||
kvm_mmu_reset_context(vcpu);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_smm_changed);
|
||||
|
||||
void process_smi(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
|
||||
@@ -2222,6 +2222,10 @@ static int shutdown_interception(struct kvm_vcpu *vcpu)
|
||||
*/
|
||||
if (!sev_es_guest(vcpu->kvm)) {
|
||||
clear_page(svm->vmcb);
|
||||
#ifdef CONFIG_KVM_SMM
|
||||
if (is_smm(vcpu))
|
||||
kvm_smm_changed(vcpu, false);
|
||||
#endif
|
||||
kvm_vcpu_reset(vcpu, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ static void timeouts_init(struct ivpu_device *vdev)
|
||||
else
|
||||
vdev->timeout.autosuspend = 100;
|
||||
vdev->timeout.d0i3_entry_msg = 5;
|
||||
vdev->timeout.state_dump_msg = 10;
|
||||
vdev->timeout.state_dump_msg = 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ int __init clocksource_i8253_init(void)
|
||||
#ifdef CONFIG_CLKEVT_I8253
|
||||
void clockevent_i8253_disable(void)
|
||||
{
|
||||
raw_spin_lock(&i8253_lock);
|
||||
guard(raw_spinlock_irqsave)(&i8253_lock);
|
||||
|
||||
/*
|
||||
* Writing the MODE register should stop the counter, according to
|
||||
@@ -132,8 +132,6 @@ void clockevent_i8253_disable(void)
|
||||
outb_p(0, PIT_CH0);
|
||||
|
||||
outb_p(0x30, PIT_MODE);
|
||||
|
||||
raw_spin_unlock(&i8253_lock);
|
||||
}
|
||||
|
||||
static int pit_shutdown(struct clock_event_device *evt)
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
#define VCN_ENC_CMD_REG_WAIT 0x0000000c
|
||||
|
||||
#define VCN_AON_SOC_ADDRESS_2_0 0x1f800
|
||||
#define VCN1_AON_SOC_ADDRESS_3_0 0x48000
|
||||
#define VCN_VID_IP_ADDRESS_2_0 0x0
|
||||
#define VCN_AON_IP_ADDRESS_2_0 0x30000
|
||||
|
||||
|
||||
@@ -42,7 +42,12 @@ static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev,
|
||||
{
|
||||
if (!ring || !ring->funcs->emit_wreg) {
|
||||
WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
|
||||
RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
|
||||
/* We just need to read back a register to post the write.
|
||||
* Reading back the remapped register causes problems on
|
||||
* some platforms so just read back the memory size register.
|
||||
*/
|
||||
if (adev->nbio.funcs->get_memsize)
|
||||
adev->nbio.funcs->get_memsize(adev);
|
||||
} else {
|
||||
amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,12 @@ static void hdp_v5_0_flush_hdp(struct amdgpu_device *adev,
|
||||
{
|
||||
if (!ring || !ring->funcs->emit_wreg) {
|
||||
WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
|
||||
RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
|
||||
/* We just need to read back a register to post the write.
|
||||
* Reading back the remapped register causes problems on
|
||||
* some platforms so just read back the memory size register.
|
||||
*/
|
||||
if (adev->nbio.funcs->get_memsize)
|
||||
adev->nbio.funcs->get_memsize(adev);
|
||||
} else {
|
||||
amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,17 @@ static void hdp_v5_2_flush_hdp(struct amdgpu_device *adev,
|
||||
if (!ring || !ring->funcs->emit_wreg) {
|
||||
WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,
|
||||
0);
|
||||
RREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
/* this is fine because SR_IOV doesn't remap the register */
|
||||
RREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
|
||||
} else {
|
||||
/* We just need to read back a register to post the write.
|
||||
* Reading back the remapped register causes problems on
|
||||
* some platforms so just read back the memory size register.
|
||||
*/
|
||||
if (adev->nbio.funcs->get_memsize)
|
||||
adev->nbio.funcs->get_memsize(adev);
|
||||
}
|
||||
} else {
|
||||
amdgpu_ring_emit_wreg(ring,
|
||||
(adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,
|
||||
|
||||
@@ -36,7 +36,12 @@ static void hdp_v6_0_flush_hdp(struct amdgpu_device *adev,
|
||||
{
|
||||
if (!ring || !ring->funcs->emit_wreg) {
|
||||
WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
|
||||
RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
|
||||
/* We just need to read back a register to post the write.
|
||||
* Reading back the remapped register causes problems on
|
||||
* some platforms so just read back the memory size register.
|
||||
*/
|
||||
if (adev->nbio.funcs->get_memsize)
|
||||
adev->nbio.funcs->get_memsize(adev);
|
||||
} else {
|
||||
amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,12 @@ static void hdp_v7_0_flush_hdp(struct amdgpu_device *adev,
|
||||
{
|
||||
if (!ring || !ring->funcs->emit_wreg) {
|
||||
WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
|
||||
RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
|
||||
/* We just need to read back a register to post the write.
|
||||
* Reading back the remapped register causes problems on
|
||||
* some platforms so just read back the memory size register.
|
||||
*/
|
||||
if (adev->nbio.funcs->get_memsize)
|
||||
adev->nbio.funcs->get_memsize(adev);
|
||||
} else {
|
||||
amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#define VCN_VID_SOC_ADDRESS_2_0 0x1fa00
|
||||
#define VCN1_VID_SOC_ADDRESS_3_0 0x48200
|
||||
#define VCN1_AON_SOC_ADDRESS_3_0 0x48000
|
||||
|
||||
#define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x1fd
|
||||
#define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x503
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#define VCN_VID_SOC_ADDRESS_2_0 0x1fa00
|
||||
#define VCN1_VID_SOC_ADDRESS_3_0 0x48200
|
||||
#define VCN1_AON_SOC_ADDRESS_3_0 0x48000
|
||||
|
||||
#define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x27
|
||||
#define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
#define VCN_VID_SOC_ADDRESS_2_0 0x1fa00
|
||||
#define VCN1_VID_SOC_ADDRESS_3_0 0x48200
|
||||
#define VCN1_AON_SOC_ADDRESS_3_0 0x48000
|
||||
|
||||
#define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x27
|
||||
#define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#define VCN_VID_SOC_ADDRESS_2_0 0x1fb00
|
||||
#define VCN1_VID_SOC_ADDRESS_3_0 0x48300
|
||||
#define VCN1_AON_SOC_ADDRESS_3_0 0x48000
|
||||
|
||||
#define VCN_HARVEST_MMSCH 0
|
||||
|
||||
@@ -575,7 +576,8 @@ static void vcn_v4_0_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx
|
||||
|
||||
/* VCN global tiling registers */
|
||||
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
|
||||
VCN, 0, regUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
|
||||
VCN, inst_idx, regUVD_GFX10_ADDR_CONFIG),
|
||||
adev->gfx.config.gb_addr_config, 0, indirect);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#define VCN_VID_SOC_ADDRESS_2_0 0x1fb00
|
||||
#define VCN1_VID_SOC_ADDRESS_3_0 0x48300
|
||||
#define VCN1_AON_SOC_ADDRESS_3_0 0x48000
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry vcn_reg_list_4_0_3[] = {
|
||||
SOC15_REG_ENTRY_STR(VCN, 0, regUVD_POWER_STATUS),
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#define VCN_VID_SOC_ADDRESS_2_0 0x1fb00
|
||||
#define VCN1_VID_SOC_ADDRESS_3_0 (0x48300 + 0x38000)
|
||||
#define VCN1_AON_SOC_ADDRESS_3_0 (0x48000 + 0x38000)
|
||||
|
||||
#define VCN_HARVEST_MMSCH 0
|
||||
|
||||
|
||||
@@ -488,7 +488,8 @@ static void vcn_v5_0_0_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_i
|
||||
|
||||
/* VCN global tiling registers */
|
||||
WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
|
||||
VCN, 0, regUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
|
||||
VCN, inst_idx, regUVD_GFX10_ADDR_CONFIG),
|
||||
adev->gfx.config.gb_addr_config, 0, indirect);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -666,15 +666,21 @@ static void dm_crtc_high_irq(void *interrupt_params)
|
||||
spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
|
||||
|
||||
if (acrtc->dm_irq_params.stream &&
|
||||
acrtc->dm_irq_params.vrr_params.supported &&
|
||||
acrtc->dm_irq_params.freesync_config.state ==
|
||||
VRR_STATE_ACTIVE_VARIABLE) {
|
||||
acrtc->dm_irq_params.vrr_params.supported) {
|
||||
bool replay_en = acrtc->dm_irq_params.stream->link->replay_settings.replay_feature_enabled;
|
||||
bool psr_en = acrtc->dm_irq_params.stream->link->psr_settings.psr_feature_enabled;
|
||||
bool fs_active_var_en = acrtc->dm_irq_params.freesync_config.state == VRR_STATE_ACTIVE_VARIABLE;
|
||||
|
||||
mod_freesync_handle_v_update(adev->dm.freesync_module,
|
||||
acrtc->dm_irq_params.stream,
|
||||
&acrtc->dm_irq_params.vrr_params);
|
||||
|
||||
dc_stream_adjust_vmin_vmax(adev->dm.dc, acrtc->dm_irq_params.stream,
|
||||
&acrtc->dm_irq_params.vrr_params.adjust);
|
||||
/* update vmin_vmax only if freesync is enabled, or only if PSR and REPLAY are disabled */
|
||||
if (fs_active_var_en || (!fs_active_var_en && !replay_en && !psr_en)) {
|
||||
dc_stream_adjust_vmin_vmax(adev->dm.dc,
|
||||
acrtc->dm_irq_params.stream,
|
||||
&acrtc->dm_irq_params.vrr_params.adjust);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -12526,7 +12532,7 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(
|
||||
* Transient states before tunneling is enabled could
|
||||
* lead to this error. We can ignore this for now.
|
||||
*/
|
||||
if (p_notify->result != AUX_RET_ERROR_PROTOCOL_ERROR) {
|
||||
if (p_notify->result == AUX_RET_ERROR_PROTOCOL_ERROR) {
|
||||
DRM_WARN("DPIA AUX failed on 0x%x(%d), error %d\n",
|
||||
payload->address, payload->length,
|
||||
p_notify->result);
|
||||
@@ -12535,22 +12541,14 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(
|
||||
goto out;
|
||||
}
|
||||
|
||||
payload->reply[0] = adev->dm.dmub_notify->aux_reply.command & 0xF;
|
||||
if (adev->dm.dmub_notify->aux_reply.command & 0xF0)
|
||||
/* The reply is stored in the top nibble of the command. */
|
||||
payload->reply[0] = (adev->dm.dmub_notify->aux_reply.command >> 4) & 0xF;
|
||||
|
||||
payload->reply[0] = adev->dm.dmub_notify->aux_reply.command;
|
||||
if (!payload->write && p_notify->aux_reply.length &&
|
||||
(payload->reply[0] == AUX_TRANSACTION_REPLY_AUX_ACK)) {
|
||||
|
||||
if (payload->length != p_notify->aux_reply.length) {
|
||||
DRM_WARN("invalid read length %d from DPIA AUX 0x%x(%d)!\n",
|
||||
p_notify->aux_reply.length,
|
||||
payload->address, payload->length);
|
||||
*operation_result = AUX_RET_ERROR_INVALID_REPLY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!payload->write && p_notify->aux_reply.length)
|
||||
memcpy(payload->data, p_notify->aux_reply.data,
|
||||
p_notify->aux_reply.length);
|
||||
}
|
||||
|
||||
/* success */
|
||||
ret = p_notify->aux_reply.length;
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
|
||||
#define PEAK_FACTOR_X1000 1006
|
||||
|
||||
/*
|
||||
* This function handles both native AUX and I2C-Over-AUX transactions.
|
||||
*/
|
||||
static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
struct drm_dp_aux_msg *msg)
|
||||
{
|
||||
@@ -87,15 +90,25 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
if (adev->dm.aux_hpd_discon_quirk) {
|
||||
if (msg->address == DP_SIDEBAND_MSG_DOWN_REQ_BASE &&
|
||||
operation_result == AUX_RET_ERROR_HPD_DISCON) {
|
||||
result = 0;
|
||||
result = msg->size;
|
||||
operation_result = AUX_RET_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (payload.write && result >= 0)
|
||||
result = msg->size;
|
||||
/*
|
||||
* result equals to 0 includes the cases of AUX_DEFER/I2C_DEFER
|
||||
*/
|
||||
if (payload.write && result >= 0) {
|
||||
if (result) {
|
||||
/*one byte indicating partially written bytes. Force 0 to retry*/
|
||||
drm_info(adev_to_drm(adev), "amdgpu: AUX partially written\n");
|
||||
result = 0;
|
||||
} else if (!payload.reply[0])
|
||||
/*I2C_ACK|AUX_ACK*/
|
||||
result = msg->size;
|
||||
}
|
||||
|
||||
if (result < 0)
|
||||
if (result < 0) {
|
||||
switch (operation_result) {
|
||||
case AUX_RET_SUCCESS:
|
||||
break;
|
||||
@@ -114,6 +127,13 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
break;
|
||||
}
|
||||
|
||||
drm_info(adev_to_drm(adev), "amdgpu: DP AUX transfer fail:%d\n", operation_result);
|
||||
}
|
||||
|
||||
if (payload.reply[0])
|
||||
drm_info(adev_to_drm(adev), "amdgpu: AUX reply command not ACK: 0x%02x.",
|
||||
payload.reply[0]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -929,7 +929,9 @@ static void populate_dml_surface_cfg_from_plane_state(enum dml_project_id dml2_p
|
||||
}
|
||||
}
|
||||
|
||||
static void get_scaler_data_for_plane(const struct dc_plane_state *in, struct dc_state *context, struct scaler_data *out)
|
||||
static struct scaler_data *get_scaler_data_for_plane(
|
||||
const struct dc_plane_state *in,
|
||||
struct dc_state *context)
|
||||
{
|
||||
int i;
|
||||
struct pipe_ctx *temp_pipe = &context->res_ctx.temp_pipe;
|
||||
@@ -950,7 +952,7 @@ static void get_scaler_data_for_plane(const struct dc_plane_state *in, struct dc
|
||||
}
|
||||
|
||||
ASSERT(i < MAX_PIPES);
|
||||
memcpy(out, &temp_pipe->plane_res.scl_data, sizeof(*out));
|
||||
return &temp_pipe->plane_res.scl_data;
|
||||
}
|
||||
|
||||
static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned int location,
|
||||
@@ -1013,11 +1015,7 @@ static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out
|
||||
const struct dc_plane_state *in, struct dc_state *context,
|
||||
const struct soc_bounding_box_st *soc)
|
||||
{
|
||||
struct scaler_data *scaler_data = kzalloc(sizeof(*scaler_data), GFP_KERNEL);
|
||||
if (!scaler_data)
|
||||
return;
|
||||
|
||||
get_scaler_data_for_plane(in, context, scaler_data);
|
||||
struct scaler_data *scaler_data = get_scaler_data_for_plane(in, context);
|
||||
|
||||
out->CursorBPP[location] = dml_cur_32bit;
|
||||
out->CursorWidth[location] = 256;
|
||||
@@ -1082,8 +1080,6 @@ static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out
|
||||
out->DynamicMetadataTransmittedBytes[location] = 0;
|
||||
|
||||
out->NumberOfCursors[location] = 1;
|
||||
|
||||
kfree(scaler_data);
|
||||
}
|
||||
|
||||
static unsigned int map_stream_to_dml_display_cfg(const struct dml2_context *dml2,
|
||||
|
||||
@@ -728,11 +728,16 @@ v3d_gpu_reset_for_timeout(struct v3d_dev *v3d, struct drm_sched_job *sched_job)
|
||||
return DRM_GPU_SCHED_STAT_NOMINAL;
|
||||
}
|
||||
|
||||
/* If the current address or return address have changed, then the GPU
|
||||
* has probably made progress and we should delay the reset. This
|
||||
* could fail if the GPU got in an infinite loop in the CL, but that
|
||||
* is pretty unlikely outside of an i-g-t testcase.
|
||||
*/
|
||||
static void
|
||||
v3d_sched_skip_reset(struct drm_sched_job *sched_job)
|
||||
{
|
||||
struct drm_gpu_scheduler *sched = sched_job->sched;
|
||||
|
||||
spin_lock(&sched->job_list_lock);
|
||||
list_add(&sched_job->list, &sched->pending_list);
|
||||
spin_unlock(&sched->job_list_lock);
|
||||
}
|
||||
|
||||
static enum drm_gpu_sched_stat
|
||||
v3d_cl_job_timedout(struct drm_sched_job *sched_job, enum v3d_queue q,
|
||||
u32 *timedout_ctca, u32 *timedout_ctra)
|
||||
@@ -742,9 +747,16 @@ v3d_cl_job_timedout(struct drm_sched_job *sched_job, enum v3d_queue q,
|
||||
u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(q));
|
||||
u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(q));
|
||||
|
||||
/* If the current address or return address have changed, then the GPU
|
||||
* has probably made progress and we should delay the reset. This
|
||||
* could fail if the GPU got in an infinite loop in the CL, but that
|
||||
* is pretty unlikely outside of an i-g-t testcase.
|
||||
*/
|
||||
if (*timedout_ctca != ctca || *timedout_ctra != ctra) {
|
||||
*timedout_ctca = ctca;
|
||||
*timedout_ctra = ctra;
|
||||
|
||||
v3d_sched_skip_reset(sched_job);
|
||||
return DRM_GPU_SCHED_STAT_NOMINAL;
|
||||
}
|
||||
|
||||
@@ -784,11 +796,13 @@ v3d_csd_job_timedout(struct drm_sched_job *sched_job)
|
||||
struct v3d_dev *v3d = job->base.v3d;
|
||||
u32 batches = V3D_CORE_READ(0, V3D_CSD_CURRENT_CFG4(v3d->ver));
|
||||
|
||||
/* If we've made progress, skip reset and let the timer get
|
||||
* rearmed.
|
||||
/* If we've made progress, skip reset, add the job to the pending
|
||||
* list, and let the timer get rearmed.
|
||||
*/
|
||||
if (job->timedout_batches != batches) {
|
||||
job->timedout_batches = batches;
|
||||
|
||||
v3d_sched_skip_reset(sched_job);
|
||||
return DRM_GPU_SCHED_STAT_NOMINAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -423,9 +423,16 @@ static int xe_alloc_pf_queue(struct xe_gt *gt, struct pf_queue *pf_queue)
|
||||
num_eus = bitmap_weight(gt->fuse_topo.eu_mask_per_dss,
|
||||
XE_MAX_EU_FUSE_BITS) * num_dss;
|
||||
|
||||
/* user can issue separate page faults per EU and per CS */
|
||||
/*
|
||||
* user can issue separate page faults per EU and per CS
|
||||
*
|
||||
* XXX: Multiplier required as compute UMD are getting PF queue errors
|
||||
* without it. Follow on why this multiplier is required.
|
||||
*/
|
||||
#define PF_MULTIPLIER 8
|
||||
pf_queue->num_dw =
|
||||
(num_eus + XE_NUM_HW_ENGINES) * PF_MSG_LEN_DW;
|
||||
(num_eus + XE_NUM_HW_ENGINES) * PF_MSG_LEN_DW * PF_MULTIPLIER;
|
||||
#undef PF_MULTIPLIER
|
||||
|
||||
pf_queue->gt = gt;
|
||||
pf_queue->data = devm_kcalloc(xe->drm.dev, pf_queue->num_dw,
|
||||
|
||||
@@ -211,9 +211,9 @@ static const struct iio_chan_spec adis16201_channels[] = {
|
||||
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
|
||||
ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC_REG, ADIS16201_SCAN_AUX_ADC, 0, 12),
|
||||
ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT_REG, ADIS16201_SCAN_INCLI_X,
|
||||
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
|
||||
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 12),
|
||||
ADIS_INCLI_CHAN(Y, ADIS16201_YINCL_OUT_REG, ADIS16201_SCAN_INCLI_Y,
|
||||
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
|
||||
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 12),
|
||||
IIO_CHAN_SOFT_TIMESTAMP(7)
|
||||
};
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ static int ad7606_spi_reg_read(struct ad7606_state *st, unsigned int addr)
|
||||
{
|
||||
.tx_buf = &st->d16[0],
|
||||
.len = 2,
|
||||
.cs_change = 0,
|
||||
.cs_change = 1,
|
||||
}, {
|
||||
.rx_buf = &st->d16[1],
|
||||
.len = 2,
|
||||
|
||||
@@ -480,15 +480,6 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
|
||||
if (info->reset)
|
||||
rockchip_saradc_reset_controller(info->reset);
|
||||
|
||||
/*
|
||||
* Use a default value for the converter clock.
|
||||
* This may become user-configurable in the future.
|
||||
*/
|
||||
ret = clk_set_rate(info->clk, info->data->clk_rate);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"failed to set adc clk rate\n");
|
||||
|
||||
ret = regulator_enable(info->vref);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
@@ -515,6 +506,14 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(info->clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(info->clk),
|
||||
"failed to get adc clock\n");
|
||||
/*
|
||||
* Use a default value for the converter clock.
|
||||
* This may become user-configurable in the future.
|
||||
*/
|
||||
ret = clk_set_rate(info->clk, info->data->clk_rate);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"failed to set adc clk rate\n");
|
||||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
|
||||
u16 fifo_count;
|
||||
u32 fifo_period;
|
||||
s64 timestamp;
|
||||
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
|
||||
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] __aligned(8);
|
||||
size_t i, nb;
|
||||
|
||||
mutex_lock(&st->lock);
|
||||
|
||||
@@ -392,6 +392,9 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
|
||||
if (fifo_status & cpu_to_le16(ST_LSM6DSX_FIFO_EMPTY_MASK))
|
||||
return 0;
|
||||
|
||||
if (!pattern_len)
|
||||
pattern_len = ST_LSM6DSX_SAMPLE_SIZE;
|
||||
|
||||
fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
|
||||
ST_LSM6DSX_CHAN_SIZE;
|
||||
fifo_len = (fifo_len / pattern_len) * pattern_len;
|
||||
@@ -623,6 +626,9 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
|
||||
if (!fifo_len)
|
||||
return 0;
|
||||
|
||||
if (!pattern_len)
|
||||
pattern_len = ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
|
||||
|
||||
for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
|
||||
err = st_lsm6dsx_read_block(hw,
|
||||
ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR,
|
||||
|
||||
@@ -121,7 +121,7 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Get and enable clock if any specified */
|
||||
uhci->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
uhci->clk = devm_clk_get_optional(&pdev->dev, NULL);
|
||||
if (IS_ERR(uhci->clk)) {
|
||||
ret = PTR_ERR(uhci->clk);
|
||||
goto err_rmr;
|
||||
|
||||
@@ -217,6 +217,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
|
||||
* buffering it.
|
||||
*/
|
||||
if (dma_capable(dev, dev_addr, size, true) &&
|
||||
!dma_kmalloc_needs_bounce(dev, size, dir) &&
|
||||
!range_straddles_page_boundary(phys, size) &&
|
||||
!xen_arch_need_swiotlb(dev, phys, dev_addr) &&
|
||||
!is_swiotlb_force_bounce(dev))
|
||||
|
||||
@@ -77,6 +77,7 @@ enum xb_req_state {
|
||||
struct xb_req_data {
|
||||
struct list_head list;
|
||||
wait_queue_head_t wq;
|
||||
struct kref kref;
|
||||
struct xsd_sockmsg msg;
|
||||
uint32_t caller_req_id;
|
||||
enum xsd_sockmsg_type type;
|
||||
@@ -103,6 +104,7 @@ int xb_init_comms(void);
|
||||
void xb_deinit_comms(void);
|
||||
int xs_watch_msg(struct xs_watch_event *event);
|
||||
void xs_request_exit(struct xb_req_data *req);
|
||||
void xs_free_req(struct kref *kref);
|
||||
|
||||
int xenbus_match(struct device *_dev, const struct device_driver *_drv);
|
||||
int xenbus_dev_probe(struct device *_dev);
|
||||
|
||||
@@ -309,8 +309,8 @@ static int process_msg(void)
|
||||
virt_wmb();
|
||||
req->state = xb_req_state_got_reply;
|
||||
req->cb(req);
|
||||
} else
|
||||
kfree(req);
|
||||
}
|
||||
kref_put(&req->kref, xs_free_req);
|
||||
}
|
||||
|
||||
mutex_unlock(&xs_response_mutex);
|
||||
@@ -386,14 +386,13 @@ static int process_writes(void)
|
||||
state.req->msg.type = XS_ERROR;
|
||||
state.req->err = err;
|
||||
list_del(&state.req->list);
|
||||
if (state.req->state == xb_req_state_aborted)
|
||||
kfree(state.req);
|
||||
else {
|
||||
if (state.req->state != xb_req_state_aborted) {
|
||||
/* write err, then update state */
|
||||
virt_wmb();
|
||||
state.req->state = xb_req_state_got_reply;
|
||||
wake_up(&state.req->wq);
|
||||
}
|
||||
kref_put(&state.req->kref, xs_free_req);
|
||||
|
||||
mutex_unlock(&xb_write_mutex);
|
||||
|
||||
|
||||
@@ -406,7 +406,7 @@ void xenbus_dev_queue_reply(struct xb_req_data *req)
|
||||
mutex_unlock(&u->reply_mutex);
|
||||
|
||||
kfree(req->body);
|
||||
kfree(req);
|
||||
kref_put(&req->kref, xs_free_req);
|
||||
|
||||
kref_put(&u->kref, xenbus_file_free);
|
||||
|
||||
|
||||
@@ -112,6 +112,12 @@ static void xs_suspend_exit(void)
|
||||
wake_up_all(&xs_state_enter_wq);
|
||||
}
|
||||
|
||||
void xs_free_req(struct kref *kref)
|
||||
{
|
||||
struct xb_req_data *req = container_of(kref, struct xb_req_data, kref);
|
||||
kfree(req);
|
||||
}
|
||||
|
||||
static uint32_t xs_request_enter(struct xb_req_data *req)
|
||||
{
|
||||
uint32_t rq_id;
|
||||
@@ -237,6 +243,12 @@ static void xs_send(struct xb_req_data *req, struct xsd_sockmsg *msg)
|
||||
req->caller_req_id = req->msg.req_id;
|
||||
req->msg.req_id = xs_request_enter(req);
|
||||
|
||||
/*
|
||||
* Take 2nd ref. One for this thread, and the second for the
|
||||
* xenbus_thread.
|
||||
*/
|
||||
kref_get(&req->kref);
|
||||
|
||||
mutex_lock(&xb_write_mutex);
|
||||
list_add_tail(&req->list, &xb_write_list);
|
||||
notify = list_is_singular(&xb_write_list);
|
||||
@@ -261,8 +273,8 @@ static void *xs_wait_for_reply(struct xb_req_data *req, struct xsd_sockmsg *msg)
|
||||
if (req->state == xb_req_state_queued ||
|
||||
req->state == xb_req_state_wait_reply)
|
||||
req->state = xb_req_state_aborted;
|
||||
else
|
||||
kfree(req);
|
||||
|
||||
kref_put(&req->kref, xs_free_req);
|
||||
mutex_unlock(&xb_write_mutex);
|
||||
|
||||
return ret;
|
||||
@@ -291,6 +303,7 @@ int xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void *par)
|
||||
req->cb = xenbus_dev_queue_reply;
|
||||
req->par = par;
|
||||
req->user_req = true;
|
||||
kref_init(&req->kref);
|
||||
|
||||
xs_send(req, msg);
|
||||
|
||||
@@ -319,6 +332,7 @@ static void *xs_talkv(struct xenbus_transaction t,
|
||||
req->num_vecs = num_vecs;
|
||||
req->cb = xs_wake_up;
|
||||
req->user_req = false;
|
||||
kref_init(&req->kref);
|
||||
|
||||
msg.req_id = 0;
|
||||
msg.tx_id = t.id;
|
||||
|
||||
@@ -174,7 +174,7 @@ int ocfs2_recovery_init(struct ocfs2_super *osb)
|
||||
struct ocfs2_recovery_map *rm;
|
||||
|
||||
mutex_init(&osb->recovery_lock);
|
||||
osb->disable_recovery = 0;
|
||||
osb->recovery_state = OCFS2_REC_ENABLED;
|
||||
osb->recovery_thread_task = NULL;
|
||||
init_waitqueue_head(&osb->recovery_event);
|
||||
|
||||
@@ -190,31 +190,53 @@ int ocfs2_recovery_init(struct ocfs2_super *osb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we can't grab the goofy sem lock from inside wait_event, so we use
|
||||
* memory barriers to make sure that we'll see the null task before
|
||||
* being woken up */
|
||||
static int ocfs2_recovery_thread_running(struct ocfs2_super *osb)
|
||||
{
|
||||
mb();
|
||||
return osb->recovery_thread_task != NULL;
|
||||
}
|
||||
|
||||
static void ocfs2_recovery_disable(struct ocfs2_super *osb,
|
||||
enum ocfs2_recovery_state state)
|
||||
{
|
||||
mutex_lock(&osb->recovery_lock);
|
||||
/*
|
||||
* If recovery thread is not running, we can directly transition to
|
||||
* final state.
|
||||
*/
|
||||
if (!ocfs2_recovery_thread_running(osb)) {
|
||||
osb->recovery_state = state + 1;
|
||||
goto out_lock;
|
||||
}
|
||||
osb->recovery_state = state;
|
||||
/* Wait for recovery thread to acknowledge state transition */
|
||||
wait_event_cmd(osb->recovery_event,
|
||||
!ocfs2_recovery_thread_running(osb) ||
|
||||
osb->recovery_state >= state + 1,
|
||||
mutex_unlock(&osb->recovery_lock),
|
||||
mutex_lock(&osb->recovery_lock));
|
||||
out_lock:
|
||||
mutex_unlock(&osb->recovery_lock);
|
||||
|
||||
/*
|
||||
* At this point we know that no more recovery work can be queued so
|
||||
* wait for any recovery completion work to complete.
|
||||
*/
|
||||
if (osb->ocfs2_wq)
|
||||
flush_workqueue(osb->ocfs2_wq);
|
||||
}
|
||||
|
||||
void ocfs2_recovery_disable_quota(struct ocfs2_super *osb)
|
||||
{
|
||||
ocfs2_recovery_disable(osb, OCFS2_REC_QUOTA_WANT_DISABLE);
|
||||
}
|
||||
|
||||
void ocfs2_recovery_exit(struct ocfs2_super *osb)
|
||||
{
|
||||
struct ocfs2_recovery_map *rm;
|
||||
|
||||
/* disable any new recovery threads and wait for any currently
|
||||
* running ones to exit. Do this before setting the vol_state. */
|
||||
mutex_lock(&osb->recovery_lock);
|
||||
osb->disable_recovery = 1;
|
||||
mutex_unlock(&osb->recovery_lock);
|
||||
wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb));
|
||||
|
||||
/* At this point, we know that no more recovery threads can be
|
||||
* launched, so wait for any recovery completion work to
|
||||
* complete. */
|
||||
if (osb->ocfs2_wq)
|
||||
flush_workqueue(osb->ocfs2_wq);
|
||||
ocfs2_recovery_disable(osb, OCFS2_REC_WANT_DISABLE);
|
||||
|
||||
/*
|
||||
* Now that recovery is shut down, and the osb is about to be
|
||||
@@ -1472,6 +1494,18 @@ static int __ocfs2_recovery_thread(void *arg)
|
||||
}
|
||||
}
|
||||
restart:
|
||||
if (quota_enabled) {
|
||||
mutex_lock(&osb->recovery_lock);
|
||||
/* Confirm that recovery thread will no longer recover quotas */
|
||||
if (osb->recovery_state == OCFS2_REC_QUOTA_WANT_DISABLE) {
|
||||
osb->recovery_state = OCFS2_REC_QUOTA_DISABLED;
|
||||
wake_up(&osb->recovery_event);
|
||||
}
|
||||
if (osb->recovery_state >= OCFS2_REC_QUOTA_DISABLED)
|
||||
quota_enabled = 0;
|
||||
mutex_unlock(&osb->recovery_lock);
|
||||
}
|
||||
|
||||
status = ocfs2_super_lock(osb, 1);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
@@ -1569,27 +1603,29 @@ bail:
|
||||
|
||||
ocfs2_free_replay_slots(osb);
|
||||
osb->recovery_thread_task = NULL;
|
||||
mb(); /* sync with ocfs2_recovery_thread_running */
|
||||
if (osb->recovery_state == OCFS2_REC_WANT_DISABLE)
|
||||
osb->recovery_state = OCFS2_REC_DISABLED;
|
||||
wake_up(&osb->recovery_event);
|
||||
|
||||
mutex_unlock(&osb->recovery_lock);
|
||||
|
||||
if (quota_enabled)
|
||||
kfree(rm_quota);
|
||||
kfree(rm_quota);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
|
||||
{
|
||||
int was_set = -1;
|
||||
|
||||
mutex_lock(&osb->recovery_lock);
|
||||
if (osb->recovery_state < OCFS2_REC_WANT_DISABLE)
|
||||
was_set = ocfs2_recovery_map_set(osb, node_num);
|
||||
|
||||
trace_ocfs2_recovery_thread(node_num, osb->node_num,
|
||||
osb->disable_recovery, osb->recovery_thread_task,
|
||||
osb->disable_recovery ?
|
||||
-1 : ocfs2_recovery_map_set(osb, node_num));
|
||||
osb->recovery_state, osb->recovery_thread_task, was_set);
|
||||
|
||||
if (osb->disable_recovery)
|
||||
if (osb->recovery_state >= OCFS2_REC_WANT_DISABLE)
|
||||
goto out;
|
||||
|
||||
if (osb->recovery_thread_task)
|
||||
|
||||
@@ -148,6 +148,7 @@ void ocfs2_wait_for_recovery(struct ocfs2_super *osb);
|
||||
|
||||
int ocfs2_recovery_init(struct ocfs2_super *osb);
|
||||
void ocfs2_recovery_exit(struct ocfs2_super *osb);
|
||||
void ocfs2_recovery_disable_quota(struct ocfs2_super *osb);
|
||||
|
||||
int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
|
||||
void ocfs2_free_replay_slots(struct ocfs2_super *osb);
|
||||
|
||||
@@ -308,6 +308,21 @@ enum ocfs2_journal_trigger_type {
|
||||
void ocfs2_initialize_journal_triggers(struct super_block *sb,
|
||||
struct ocfs2_triggers triggers[]);
|
||||
|
||||
enum ocfs2_recovery_state {
|
||||
OCFS2_REC_ENABLED = 0,
|
||||
OCFS2_REC_QUOTA_WANT_DISABLE,
|
||||
/*
|
||||
* Must be OCFS2_REC_QUOTA_WANT_DISABLE + 1 for
|
||||
* ocfs2_recovery_disable_quota() to work.
|
||||
*/
|
||||
OCFS2_REC_QUOTA_DISABLED,
|
||||
OCFS2_REC_WANT_DISABLE,
|
||||
/*
|
||||
* Must be OCFS2_REC_WANT_DISABLE + 1 for ocfs2_recovery_exit() to work
|
||||
*/
|
||||
OCFS2_REC_DISABLED,
|
||||
};
|
||||
|
||||
struct ocfs2_journal;
|
||||
struct ocfs2_slot_info;
|
||||
struct ocfs2_recovery_map;
|
||||
@@ -370,7 +385,7 @@ struct ocfs2_super
|
||||
struct ocfs2_recovery_map *recovery_map;
|
||||
struct ocfs2_replay_map *replay_map;
|
||||
struct task_struct *recovery_thread_task;
|
||||
int disable_recovery;
|
||||
enum ocfs2_recovery_state recovery_state;
|
||||
wait_queue_head_t checkpoint_event;
|
||||
struct ocfs2_journal *journal;
|
||||
unsigned long osb_commit_interval;
|
||||
|
||||
@@ -453,8 +453,7 @@ out:
|
||||
|
||||
/* Sync changes in local quota file into global quota file and
|
||||
* reinitialize local quota file.
|
||||
* The function expects local quota file to be already locked and
|
||||
* s_umount locked in shared mode. */
|
||||
* The function expects local quota file to be already locked. */
|
||||
static int ocfs2_recover_local_quota_file(struct inode *lqinode,
|
||||
int type,
|
||||
struct ocfs2_quota_recovery *rec)
|
||||
@@ -588,7 +587,6 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
|
||||
{
|
||||
unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,
|
||||
LOCAL_GROUP_QUOTA_SYSTEM_INODE };
|
||||
struct super_block *sb = osb->sb;
|
||||
struct ocfs2_local_disk_dqinfo *ldinfo;
|
||||
struct buffer_head *bh;
|
||||
handle_t *handle;
|
||||
@@ -600,7 +598,6 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
|
||||
printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
|
||||
"slot %u\n", osb->dev_str, slot_num);
|
||||
|
||||
down_read(&sb->s_umount);
|
||||
for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
|
||||
if (list_empty(&(rec->r_list[type])))
|
||||
continue;
|
||||
@@ -677,7 +674,6 @@ out_put:
|
||||
break;
|
||||
}
|
||||
out:
|
||||
up_read(&sb->s_umount);
|
||||
kfree(rec);
|
||||
return status;
|
||||
}
|
||||
@@ -843,8 +839,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
|
||||
ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
|
||||
|
||||
/*
|
||||
* s_umount held in exclusive mode protects us against racing with
|
||||
* recovery thread...
|
||||
* ocfs2_dismount_volume() has already aborted quota recovery...
|
||||
*/
|
||||
if (oinfo->dqi_rec) {
|
||||
ocfs2_free_quota_recovery(oinfo->dqi_rec);
|
||||
|
||||
@@ -698,10 +698,12 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
|
||||
|
||||
bg_bh = ocfs2_block_group_alloc_contig(osb, handle, alloc_inode,
|
||||
ac, cl);
|
||||
if (PTR_ERR(bg_bh) == -ENOSPC)
|
||||
if (PTR_ERR(bg_bh) == -ENOSPC) {
|
||||
ac->ac_which = OCFS2_AC_USE_MAIN_DISCONTIG;
|
||||
bg_bh = ocfs2_block_group_alloc_discontig(handle,
|
||||
alloc_inode,
|
||||
ac, cl);
|
||||
}
|
||||
if (IS_ERR(bg_bh)) {
|
||||
status = PTR_ERR(bg_bh);
|
||||
bg_bh = NULL;
|
||||
@@ -1794,6 +1796,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
|
||||
{
|
||||
int status;
|
||||
u16 chain;
|
||||
u32 contig_bits;
|
||||
u64 next_group;
|
||||
struct inode *alloc_inode = ac->ac_inode;
|
||||
struct buffer_head *group_bh = NULL;
|
||||
@@ -1819,10 +1822,21 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
|
||||
status = -ENOSPC;
|
||||
/* for now, the chain search is a bit simplistic. We just use
|
||||
* the 1st group with any empty bits. */
|
||||
while ((status = ac->ac_group_search(alloc_inode, group_bh,
|
||||
bits_wanted, min_bits,
|
||||
ac->ac_max_block,
|
||||
res)) == -ENOSPC) {
|
||||
while (1) {
|
||||
if (ac->ac_which == OCFS2_AC_USE_MAIN_DISCONTIG) {
|
||||
contig_bits = le16_to_cpu(bg->bg_contig_free_bits);
|
||||
if (!contig_bits)
|
||||
contig_bits = ocfs2_find_max_contig_free_bits(bg->bg_bitmap,
|
||||
le16_to_cpu(bg->bg_bits), 0);
|
||||
if (bits_wanted > contig_bits && contig_bits >= min_bits)
|
||||
bits_wanted = contig_bits;
|
||||
}
|
||||
|
||||
status = ac->ac_group_search(alloc_inode, group_bh,
|
||||
bits_wanted, min_bits,
|
||||
ac->ac_max_block, res);
|
||||
if (status != -ENOSPC)
|
||||
break;
|
||||
if (!bg->bg_next_group)
|
||||
break;
|
||||
|
||||
@@ -1982,6 +1996,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac,
|
||||
victim = ocfs2_find_victim_chain(cl);
|
||||
ac->ac_chain = victim;
|
||||
|
||||
search:
|
||||
status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits,
|
||||
res, &bits_left);
|
||||
if (!status) {
|
||||
@@ -2022,6 +2037,16 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac,
|
||||
}
|
||||
}
|
||||
|
||||
/* Chains can't supply the bits_wanted contiguous space.
|
||||
* We should switch to using every single bit when allocating
|
||||
* from the global bitmap. */
|
||||
if (i == le16_to_cpu(cl->cl_next_free_rec) &&
|
||||
status == -ENOSPC && ac->ac_which == OCFS2_AC_USE_MAIN) {
|
||||
ac->ac_which = OCFS2_AC_USE_MAIN_DISCONTIG;
|
||||
ac->ac_chain = victim;
|
||||
goto search;
|
||||
}
|
||||
|
||||
set_hint:
|
||||
if (status != -ENOSPC) {
|
||||
/* If the next search of this group is not likely to
|
||||
@@ -2365,7 +2390,8 @@ int __ocfs2_claim_clusters(handle_t *handle,
|
||||
BUG_ON(ac->ac_bits_given >= ac->ac_bits_wanted);
|
||||
|
||||
BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL
|
||||
&& ac->ac_which != OCFS2_AC_USE_MAIN);
|
||||
&& ac->ac_which != OCFS2_AC_USE_MAIN
|
||||
&& ac->ac_which != OCFS2_AC_USE_MAIN_DISCONTIG);
|
||||
|
||||
if (ac->ac_which == OCFS2_AC_USE_LOCAL) {
|
||||
WARN_ON(min_clusters > 1);
|
||||
|
||||
@@ -29,6 +29,7 @@ struct ocfs2_alloc_context {
|
||||
#define OCFS2_AC_USE_MAIN 2
|
||||
#define OCFS2_AC_USE_INODE 3
|
||||
#define OCFS2_AC_USE_META 4
|
||||
#define OCFS2_AC_USE_MAIN_DISCONTIG 5
|
||||
u32 ac_which;
|
||||
|
||||
/* these are used by the chain search */
|
||||
|
||||
@@ -1868,6 +1868,9 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
|
||||
/* Orphan scan should be stopped as early as possible */
|
||||
ocfs2_orphan_scan_stop(osb);
|
||||
|
||||
/* Stop quota recovery so that we can disable quotas */
|
||||
ocfs2_recovery_disable_quota(osb);
|
||||
|
||||
ocfs2_disable_quotas(osb);
|
||||
|
||||
/* All dquots should be freed by now */
|
||||
|
||||
@@ -29,7 +29,6 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
|
||||
{
|
||||
struct cached_fid *cfid;
|
||||
|
||||
spin_lock(&cfids->cfid_list_lock);
|
||||
list_for_each_entry(cfid, &cfids->entries, entry) {
|
||||
if (!strcmp(cfid->path, path)) {
|
||||
/*
|
||||
@@ -38,25 +37,20 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
|
||||
* being deleted due to a lease break.
|
||||
*/
|
||||
if (!cfid->time || !cfid->has_lease) {
|
||||
spin_unlock(&cfids->cfid_list_lock);
|
||||
return NULL;
|
||||
}
|
||||
kref_get(&cfid->refcount);
|
||||
spin_unlock(&cfids->cfid_list_lock);
|
||||
return cfid;
|
||||
}
|
||||
}
|
||||
if (lookup_only) {
|
||||
spin_unlock(&cfids->cfid_list_lock);
|
||||
return NULL;
|
||||
}
|
||||
if (cfids->num_entries >= max_cached_dirs) {
|
||||
spin_unlock(&cfids->cfid_list_lock);
|
||||
return NULL;
|
||||
}
|
||||
cfid = init_cached_dir(path);
|
||||
if (cfid == NULL) {
|
||||
spin_unlock(&cfids->cfid_list_lock);
|
||||
return NULL;
|
||||
}
|
||||
cfid->cfids = cfids;
|
||||
@@ -74,7 +68,6 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
|
||||
*/
|
||||
cfid->has_lease = true;
|
||||
|
||||
spin_unlock(&cfids->cfid_list_lock);
|
||||
return cfid;
|
||||
}
|
||||
|
||||
@@ -185,8 +178,10 @@ replay_again:
|
||||
if (!utf16_path)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock(&cfids->cfid_list_lock);
|
||||
cfid = find_or_create_cached_dir(cfids, path, lookup_only, tcon->max_cached_dirs);
|
||||
if (cfid == NULL) {
|
||||
spin_unlock(&cfids->cfid_list_lock);
|
||||
kfree(utf16_path);
|
||||
return -ENOENT;
|
||||
}
|
||||
@@ -195,7 +190,6 @@ replay_again:
|
||||
* Otherwise, it is either a new entry or laundromat worker removed it
|
||||
* from @cfids->entries. Caller will put last reference if the latter.
|
||||
*/
|
||||
spin_lock(&cfids->cfid_list_lock);
|
||||
if (cfid->has_lease && cfid->time) {
|
||||
spin_unlock(&cfids->cfid_list_lock);
|
||||
*ret_cfid = cfid;
|
||||
|
||||
@@ -1586,8 +1586,11 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx,
|
||||
user_uffdio_copy = (struct uffdio_copy __user *) arg;
|
||||
|
||||
ret = -EAGAIN;
|
||||
if (atomic_read(&ctx->mmap_changing))
|
||||
if (unlikely(atomic_read(&ctx->mmap_changing))) {
|
||||
if (unlikely(put_user(ret, &user_uffdio_copy->copy)))
|
||||
return -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = -EFAULT;
|
||||
if (copy_from_user(&uffdio_copy, user_uffdio_copy,
|
||||
@@ -1642,8 +1645,11 @@ static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx,
|
||||
user_uffdio_zeropage = (struct uffdio_zeropage __user *) arg;
|
||||
|
||||
ret = -EAGAIN;
|
||||
if (atomic_read(&ctx->mmap_changing))
|
||||
if (unlikely(atomic_read(&ctx->mmap_changing))) {
|
||||
if (unlikely(put_user(ret, &user_uffdio_zeropage->zeropage)))
|
||||
return -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = -EFAULT;
|
||||
if (copy_from_user(&uffdio_zeropage, user_uffdio_zeropage,
|
||||
@@ -1745,8 +1751,11 @@ static int userfaultfd_continue(struct userfaultfd_ctx *ctx, unsigned long arg)
|
||||
user_uffdio_continue = (struct uffdio_continue __user *)arg;
|
||||
|
||||
ret = -EAGAIN;
|
||||
if (atomic_read(&ctx->mmap_changing))
|
||||
if (unlikely(atomic_read(&ctx->mmap_changing))) {
|
||||
if (unlikely(put_user(ret, &user_uffdio_continue->mapped)))
|
||||
return -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = -EFAULT;
|
||||
if (copy_from_user(&uffdio_continue, user_uffdio_continue,
|
||||
@@ -1802,8 +1811,11 @@ static inline int userfaultfd_poison(struct userfaultfd_ctx *ctx, unsigned long
|
||||
user_uffdio_poison = (struct uffdio_poison __user *)arg;
|
||||
|
||||
ret = -EAGAIN;
|
||||
if (atomic_read(&ctx->mmap_changing))
|
||||
if (unlikely(atomic_read(&ctx->mmap_changing))) {
|
||||
if (unlikely(put_user(ret, &user_uffdio_poison->updated)))
|
||||
return -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = -EFAULT;
|
||||
if (copy_from_user(&uffdio_poison, user_uffdio_poison,
|
||||
@@ -1871,8 +1883,12 @@ static int userfaultfd_move(struct userfaultfd_ctx *ctx,
|
||||
|
||||
user_uffdio_move = (struct uffdio_move __user *) arg;
|
||||
|
||||
if (atomic_read(&ctx->mmap_changing))
|
||||
return -EAGAIN;
|
||||
ret = -EAGAIN;
|
||||
if (unlikely(atomic_read(&ctx->mmap_changing))) {
|
||||
if (unlikely(put_user(ret, &user_uffdio_move->move)))
|
||||
return -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (copy_from_user(&uffdio_move, user_uffdio_move,
|
||||
/* don't copy "move" last field */
|
||||
|
||||
@@ -884,6 +884,14 @@ bool io_req_post_cqe(struct io_kiocb *req, s32 res, u32 cflags)
|
||||
struct io_ring_ctx *ctx = req->ctx;
|
||||
bool posted;
|
||||
|
||||
/*
|
||||
* If multishot has already posted deferred completions, ensure that
|
||||
* those are flushed first before posting this one. If not, CQEs
|
||||
* could get reordered.
|
||||
*/
|
||||
if (!wq_list_empty(&ctx->submit_state.compl_reqs))
|
||||
__io_submit_flush_completions(ctx);
|
||||
|
||||
lockdep_assert(!io_wq_current_is_worker());
|
||||
lockdep_assert_held(&ctx->uring_lock);
|
||||
|
||||
|
||||
@@ -949,7 +949,9 @@ struct kset *module_kset;
|
||||
static void module_kobj_release(struct kobject *kobj)
|
||||
{
|
||||
struct module_kobject *mk = to_module_kobject(kobj);
|
||||
complete(mk->kobj_completion);
|
||||
|
||||
if (mk->kobj_completion)
|
||||
complete(mk->kobj_completion);
|
||||
}
|
||||
|
||||
const struct kobj_type module_ktype = {
|
||||
|
||||
@@ -2883,6 +2883,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
||||
void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,
|
||||
pmd_t *pmd, bool freeze, struct folio *folio)
|
||||
{
|
||||
bool pmd_migration = is_pmd_migration_entry(*pmd);
|
||||
|
||||
VM_WARN_ON_ONCE(folio && !folio_test_pmd_mappable(folio));
|
||||
VM_WARN_ON_ONCE(!IS_ALIGNED(address, HPAGE_PMD_SIZE));
|
||||
VM_WARN_ON_ONCE(folio && !folio_test_locked(folio));
|
||||
@@ -2893,9 +2895,12 @@ void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,
|
||||
* require a folio to check the PMD against. Otherwise, there
|
||||
* is a risk of replacing the wrong folio.
|
||||
*/
|
||||
if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) ||
|
||||
is_pmd_migration_entry(*pmd)) {
|
||||
if (folio && folio != pmd_folio(*pmd))
|
||||
if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) || pmd_migration) {
|
||||
/*
|
||||
* Do not apply pmd_folio() to a migration entry; and folio lock
|
||||
* guarantees that it must be of the wrong folio anyway.
|
||||
*/
|
||||
if (folio && (pmd_migration || folio != pmd_folio(*pmd)))
|
||||
return;
|
||||
__split_huge_pmd_locked(vma, pmd, address, freeze);
|
||||
}
|
||||
|
||||
@@ -461,7 +461,14 @@ static int __init_memblock memblock_double_array(struct memblock_type *type,
|
||||
min(new_area_start, memblock.current_limit),
|
||||
new_alloc_size, PAGE_SIZE);
|
||||
|
||||
new_array = addr ? __va(addr) : NULL;
|
||||
if (addr) {
|
||||
/* The memory may not have been accepted, yet. */
|
||||
accept_memory(addr, new_alloc_size);
|
||||
|
||||
new_array = __va(addr);
|
||||
} else {
|
||||
new_array = NULL;
|
||||
}
|
||||
}
|
||||
if (!addr) {
|
||||
pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n",
|
||||
|
||||
@@ -90,6 +90,8 @@ int check_compaction(unsigned long mem_free, unsigned long hugepage_size,
|
||||
int compaction_index = 0;
|
||||
char nr_hugepages[20] = {0};
|
||||
char init_nr_hugepages[24] = {0};
|
||||
char target_nr_hugepages[24] = {0};
|
||||
int slen;
|
||||
|
||||
snprintf(init_nr_hugepages, sizeof(init_nr_hugepages),
|
||||
"%lu", initial_nr_hugepages);
|
||||
@@ -106,11 +108,18 @@ int check_compaction(unsigned long mem_free, unsigned long hugepage_size,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Request a large number of huge pages. The Kernel will allocate
|
||||
as much as it can */
|
||||
if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) {
|
||||
ksft_print_msg("Failed to write 100000 to /proc/sys/vm/nr_hugepages: %s\n",
|
||||
strerror(errno));
|
||||
/*
|
||||
* Request huge pages for about half of the free memory. The Kernel
|
||||
* will allocate as much as it can, and we expect it will get at least 1/3
|
||||
*/
|
||||
nr_hugepages_ul = mem_free / hugepage_size / 2;
|
||||
snprintf(target_nr_hugepages, sizeof(target_nr_hugepages),
|
||||
"%lu", nr_hugepages_ul);
|
||||
|
||||
slen = strlen(target_nr_hugepages);
|
||||
if (write(fd, target_nr_hugepages, slen) != slen) {
|
||||
ksft_print_msg("Failed to write %lu to /proc/sys/vm/nr_hugepages: %s\n",
|
||||
nr_hugepages_ul, strerror(errno));
|
||||
goto close_fd;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,8 +102,18 @@ void expect_fault_on_read_execonly_key(void *p1, int pkey)
|
||||
return;
|
||||
}
|
||||
|
||||
#define REPEAT_8(s) s s s s s s s s
|
||||
#define REPEAT_64(s) REPEAT_8(s) REPEAT_8(s) REPEAT_8(s) REPEAT_8(s) \
|
||||
REPEAT_8(s) REPEAT_8(s) REPEAT_8(s) REPEAT_8(s)
|
||||
#define REPEAT_512(s) REPEAT_64(s) REPEAT_64(s) REPEAT_64(s) REPEAT_64(s) \
|
||||
REPEAT_64(s) REPEAT_64(s) REPEAT_64(s) REPEAT_64(s)
|
||||
#define REPEAT_4096(s) REPEAT_512(s) REPEAT_512(s) REPEAT_512(s) REPEAT_512(s) \
|
||||
REPEAT_512(s) REPEAT_512(s) REPEAT_512(s) REPEAT_512(s)
|
||||
#define REPEAT_16384(s) REPEAT_4096(s) REPEAT_4096(s) \
|
||||
REPEAT_4096(s) REPEAT_4096(s)
|
||||
|
||||
/* 4-byte instructions * 16384 = 64K page */
|
||||
#define __page_o_noops() asm(".rept 16384 ; nop; .endr")
|
||||
#define __page_o_noops() asm(REPEAT_16384("nop\n"))
|
||||
|
||||
void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user