mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 12:00:22 +09:00
Merge 5.15.120 into android14-5.15-lts
Changes in 5.15.120 mptcp: fix possible divide by zero in recvmsg() mptcp: consolidate fallback and non fallback state machine mm, hwpoison: try to recover from copy-on write faults mm, hwpoison: when copy-on-write hits poison, take page offline drm/amdgpu: Set vmbo destroy after pt bo is created x86/microcode/AMD: Load late on both threads too x86/smp: Use dedicated cache-line for mwait_play_dead() can: isotp: isotp_sendmsg(): fix return error fix on TX path bpf: ensure main program has an extable HID: wacom: Use ktime_t rather than int when dealing with timestamps HID: logitech-hidpp: add HIDPP_QUIRK_DELAYED_INIT for the T651. Revert "thermal/drivers/mediatek: Use devm_of_iomap to avoid resource leak in mtk_thermal_probe" perf symbols: Symbol lookup with kcore can fail if multiple segments match stext scripts/tags.sh: Resolve gtags empty index generation drm/amdgpu: Validate VM ioctl flags. parisc: Delete redundant register definitions in <asm/assembly.h> nubus: Partially revert proc_create_single_data() conversion Linux 5.15.120 Change-Id: I8a88db150d5f249ddb629df70640acbdc01551c0 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 119
|
||||
SUBLEVEL = 120
|
||||
EXTRAVERSION =
|
||||
NAME = Trick or Treat
|
||||
|
||||
|
||||
@@ -72,10 +72,6 @@
|
||||
|
||||
#include <asm/asmregs.h>
|
||||
|
||||
sp = 30
|
||||
gp = 27
|
||||
ipsw = 22
|
||||
|
||||
/*
|
||||
* We provide two versions of each macro to convert from physical
|
||||
* to virtual and vice versa. The "_r1" versions take one argument
|
||||
|
||||
@@ -699,7 +699,7 @@ static enum ucode_state apply_microcode_amd(int cpu)
|
||||
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
|
||||
|
||||
/* need to apply patch? */
|
||||
if (rev >= mc_amd->hdr.patch_id) {
|
||||
if (rev > mc_amd->hdr.patch_id) {
|
||||
ret = UCODE_OK;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -105,6 +105,17 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
|
||||
DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
|
||||
EXPORT_PER_CPU_SYMBOL(cpu_info);
|
||||
|
||||
struct mwait_cpu_dead {
|
||||
unsigned int control;
|
||||
unsigned int status;
|
||||
};
|
||||
|
||||
/*
|
||||
* Cache line aligned data for mwait_play_dead(). Separate on purpose so
|
||||
* that it's unlikely to be touched by other CPUs.
|
||||
*/
|
||||
static DEFINE_PER_CPU_ALIGNED(struct mwait_cpu_dead, mwait_cpu_dead);
|
||||
|
||||
/* Logical package management. We might want to allocate that dynamically */
|
||||
unsigned int __max_logical_packages __read_mostly;
|
||||
EXPORT_SYMBOL(__max_logical_packages);
|
||||
@@ -1685,10 +1696,10 @@ EXPORT_SYMBOL_GPL(cond_wakeup_cpu0);
|
||||
*/
|
||||
static inline void mwait_play_dead(void)
|
||||
{
|
||||
struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead);
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
unsigned int highest_cstate = 0;
|
||||
unsigned int highest_subcstate = 0;
|
||||
void *mwait_ptr;
|
||||
int i;
|
||||
|
||||
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
|
||||
@@ -1723,13 +1734,6 @@ static inline void mwait_play_dead(void)
|
||||
(highest_subcstate - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This should be a memory location in a cache line which is
|
||||
* unlikely to be touched by other processors. The actual
|
||||
* content is immaterial as it is not actually modified in any way.
|
||||
*/
|
||||
mwait_ptr = ¤t_thread_info()->flags;
|
||||
|
||||
wbinvd();
|
||||
|
||||
while (1) {
|
||||
@@ -1741,9 +1745,9 @@ static inline void mwait_play_dead(void)
|
||||
* case where we return around the loop.
|
||||
*/
|
||||
mb();
|
||||
clflush(mwait_ptr);
|
||||
clflush(md);
|
||||
mb();
|
||||
__monitor(mwait_ptr, 0, 0);
|
||||
__monitor(md, 0, 0);
|
||||
mb();
|
||||
__mwait(eax, 0);
|
||||
|
||||
|
||||
@@ -685,7 +685,6 @@ int amdgpu_bo_create_vm(struct amdgpu_device *adev,
|
||||
* num of amdgpu_vm_pt entries.
|
||||
*/
|
||||
BUG_ON(bp->bo_ptr_size < sizeof(struct amdgpu_bo_vm));
|
||||
bp->destroy = &amdgpu_bo_vm_destroy;
|
||||
r = amdgpu_bo_create(adev, bp, &bo_ptr);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -3274,6 +3274,10 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
long timeout = msecs_to_jiffies(2000);
|
||||
int r;
|
||||
|
||||
/* No valid flags defined yet */
|
||||
if (args->in.flags)
|
||||
return -EINVAL;
|
||||
|
||||
switch (args->in.op) {
|
||||
case AMDGPU_VM_OP_RESERVE_VMID:
|
||||
/* We only have requirement to reserve vmid from gfxhub */
|
||||
|
||||
@@ -4295,7 +4295,7 @@ static const struct hid_device_id hidpp_devices[] = {
|
||||
{ /* wireless touchpad T651 */
|
||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||
USB_DEVICE_ID_LOGITECH_T651),
|
||||
.driver_data = HIDPP_QUIRK_CLASS_WTP },
|
||||
.driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
|
||||
{ /* Mouse Logitech Anywhere MX */
|
||||
LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
|
||||
{ /* Mouse Logitech Cube */
|
||||
|
||||
@@ -1314,7 +1314,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
|
||||
struct input_dev *pen_input = wacom->pen_input;
|
||||
unsigned char *data = wacom->data;
|
||||
int number_of_valid_frames = 0;
|
||||
int time_interval = 15000000;
|
||||
ktime_t time_interval = 15000000;
|
||||
ktime_t time_packet_received = ktime_get();
|
||||
int i;
|
||||
|
||||
@@ -1348,7 +1348,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
|
||||
if (number_of_valid_frames) {
|
||||
if (wacom->hid_data.time_delayed)
|
||||
time_interval = ktime_get() - wacom->hid_data.time_delayed;
|
||||
time_interval /= number_of_valid_frames;
|
||||
time_interval = div_u64(time_interval, number_of_valid_frames);
|
||||
wacom->hid_data.time_delayed = time_packet_received;
|
||||
}
|
||||
|
||||
@@ -1359,7 +1359,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
|
||||
bool range = frame[0] & 0x20;
|
||||
bool invert = frame[0] & 0x10;
|
||||
int frames_number_reversed = number_of_valid_frames - i - 1;
|
||||
int event_timestamp = time_packet_received - frames_number_reversed * time_interval;
|
||||
ktime_t event_timestamp = time_packet_received - frames_number_reversed * time_interval;
|
||||
|
||||
if (!valid)
|
||||
continue;
|
||||
|
||||
@@ -321,7 +321,7 @@ struct hid_data {
|
||||
int bat_connected;
|
||||
int ps_connected;
|
||||
bool pad_input_event_flag;
|
||||
int time_delayed;
|
||||
ktime_t time_delayed;
|
||||
};
|
||||
|
||||
struct wacom_remote_data {
|
||||
|
||||
@@ -137,6 +137,18 @@ static int nubus_proc_rsrc_show(struct seq_file *m, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nubus_rsrc_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, nubus_proc_rsrc_show, inode);
|
||||
}
|
||||
|
||||
static const struct proc_ops nubus_rsrc_proc_ops = {
|
||||
.proc_open = nubus_rsrc_proc_open,
|
||||
.proc_read = seq_read,
|
||||
.proc_lseek = seq_lseek,
|
||||
.proc_release = single_release,
|
||||
};
|
||||
|
||||
void nubus_proc_add_rsrc_mem(struct proc_dir_entry *procdir,
|
||||
const struct nubus_dirent *ent,
|
||||
unsigned int size)
|
||||
@@ -152,8 +164,8 @@ void nubus_proc_add_rsrc_mem(struct proc_dir_entry *procdir,
|
||||
pde_data = nubus_proc_alloc_pde_data(nubus_dirptr(ent), size);
|
||||
else
|
||||
pde_data = NULL;
|
||||
proc_create_single_data(name, S_IFREG | 0444, procdir,
|
||||
nubus_proc_rsrc_show, pde_data);
|
||||
proc_create_data(name, S_IFREG | 0444, procdir,
|
||||
&nubus_rsrc_proc_ops, pde_data);
|
||||
}
|
||||
|
||||
void nubus_proc_add_rsrc(struct proc_dir_entry *procdir,
|
||||
@@ -166,9 +178,9 @@ void nubus_proc_add_rsrc(struct proc_dir_entry *procdir,
|
||||
return;
|
||||
|
||||
snprintf(name, sizeof(name), "%x", ent->type);
|
||||
proc_create_single_data(name, S_IFREG | 0444, procdir,
|
||||
nubus_proc_rsrc_show,
|
||||
nubus_proc_alloc_pde_data(data, 0));
|
||||
proc_create_data(name, S_IFREG | 0444, procdir,
|
||||
&nubus_rsrc_proc_ops,
|
||||
nubus_proc_alloc_pde_data(data, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1028,12 +1028,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
auxadc_base = devm_of_iomap(&pdev->dev, auxadc, 0, NULL);
|
||||
if (IS_ERR(auxadc_base)) {
|
||||
of_node_put(auxadc);
|
||||
return PTR_ERR(auxadc_base);
|
||||
}
|
||||
|
||||
auxadc_base = of_iomap(auxadc, 0);
|
||||
auxadc_phys_base = of_get_phys_base(auxadc);
|
||||
|
||||
of_node_put(auxadc);
|
||||
@@ -1049,12 +1044,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
apmixed_base = devm_of_iomap(&pdev->dev, apmixedsys, 0, NULL);
|
||||
if (IS_ERR(apmixed_base)) {
|
||||
of_node_put(apmixedsys);
|
||||
return PTR_ERR(apmixed_base);
|
||||
}
|
||||
|
||||
apmixed_base = of_iomap(apmixedsys, 0);
|
||||
apmixed_phys_base = of_get_phys_base(apmixedsys);
|
||||
|
||||
of_node_put(apmixedsys);
|
||||
|
||||
@@ -255,6 +255,30 @@ static inline void copy_user_highpage(struct page *to, struct page *from,
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef copy_mc_to_kernel
|
||||
static inline int copy_mc_user_highpage(struct page *to, struct page *from,
|
||||
unsigned long vaddr, struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long ret;
|
||||
char *vfrom, *vto;
|
||||
|
||||
vfrom = kmap_local_page(from);
|
||||
vto = kmap_local_page(to);
|
||||
ret = copy_mc_to_kernel(vto, vfrom, PAGE_SIZE);
|
||||
kunmap_local(vto);
|
||||
kunmap_local(vfrom);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline int copy_mc_user_highpage(struct page *to, struct page *from,
|
||||
unsigned long vaddr, struct vm_area_struct *vma)
|
||||
{
|
||||
copy_user_highpage(to, from, vaddr, vma);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_COPY_HIGHPAGE
|
||||
|
||||
static inline void copy_highpage(struct page *to, struct page *from)
|
||||
|
||||
@@ -3197,7 +3197,6 @@ enum mf_flags {
|
||||
MF_SOFT_OFFLINE = 1 << 3,
|
||||
};
|
||||
extern int memory_failure(unsigned long pfn, int flags);
|
||||
extern void memory_failure_queue(unsigned long pfn, int flags);
|
||||
extern void memory_failure_queue_kick(int cpu);
|
||||
extern int unpoison_memory(unsigned long pfn);
|
||||
extern int sysctl_memory_failure_early_kill;
|
||||
@@ -3206,8 +3205,12 @@ extern void shake_page(struct page *p);
|
||||
extern atomic_long_t num_poisoned_pages __read_mostly;
|
||||
extern int soft_offline_page(unsigned long pfn, int flags);
|
||||
#ifdef CONFIG_MEMORY_FAILURE
|
||||
extern void memory_failure_queue(unsigned long pfn, int flags);
|
||||
extern int __get_huge_page_for_hwpoison(unsigned long pfn, int flags);
|
||||
#else
|
||||
static inline void memory_failure_queue(unsigned long pfn, int flags)
|
||||
{
|
||||
}
|
||||
static inline int __get_huge_page_for_hwpoison(unsigned long pfn, int flags)
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -12588,9 +12588,10 @@ static int jit_subprogs(struct bpf_verifier_env *env)
|
||||
}
|
||||
|
||||
/* finally lock prog and jit images for all functions and
|
||||
* populate kallsysm
|
||||
* populate kallsysm. Begin at the first subprogram, since
|
||||
* bpf_prog_load will add the kallsyms for the main program.
|
||||
*/
|
||||
for (i = 0; i < env->subprog_cnt; i++) {
|
||||
for (i = 1; i < env->subprog_cnt; i++) {
|
||||
bpf_prog_lock_ro(func[i]);
|
||||
bpf_prog_kallsyms_add(func[i]);
|
||||
}
|
||||
@@ -12615,6 +12616,8 @@ static int jit_subprogs(struct bpf_verifier_env *env)
|
||||
|
||||
prog->jited = 1;
|
||||
prog->bpf_func = func[0]->bpf_func;
|
||||
prog->aux->extable = func[0]->aux->extable;
|
||||
prog->aux->num_exentries = func[0]->aux->num_exentries;
|
||||
prog->aux->func = func;
|
||||
prog->aux->func_cnt = env->subprog_cnt;
|
||||
bpf_prog_jit_attempt_done(prog);
|
||||
|
||||
32
mm/memory.c
32
mm/memory.c
@@ -2910,10 +2910,16 @@ static inline int pte_unmap_same(struct mm_struct *mm, pmd_t *pmd,
|
||||
return same;
|
||||
}
|
||||
|
||||
static inline bool cow_user_page(struct page *dst, struct page *src,
|
||||
struct vm_fault *vmf)
|
||||
/*
|
||||
* Return:
|
||||
* 0: copied succeeded
|
||||
* -EHWPOISON: copy failed due to hwpoison in source page
|
||||
* -EAGAIN: copied failed (some other reason)
|
||||
*/
|
||||
static inline int cow_user_page(struct page *dst, struct page *src,
|
||||
struct vm_fault *vmf)
|
||||
{
|
||||
bool ret;
|
||||
int ret;
|
||||
void *kaddr;
|
||||
void __user *uaddr;
|
||||
bool locked = false;
|
||||
@@ -2922,8 +2928,11 @@ static inline bool cow_user_page(struct page *dst, struct page *src,
|
||||
unsigned long addr = vmf->address;
|
||||
|
||||
if (likely(src)) {
|
||||
copy_user_highpage(dst, src, addr, vma);
|
||||
return true;
|
||||
if (copy_mc_user_highpage(dst, src, addr, vma)) {
|
||||
memory_failure_queue(page_to_pfn(src), 0);
|
||||
return -EHWPOISON;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2950,7 +2959,7 @@ static inline bool cow_user_page(struct page *dst, struct page *src,
|
||||
* and update local tlb only
|
||||
*/
|
||||
update_mmu_tlb(vma, addr, vmf->pte);
|
||||
ret = false;
|
||||
ret = -EAGAIN;
|
||||
goto pte_unlock;
|
||||
}
|
||||
|
||||
@@ -2975,7 +2984,7 @@ static inline bool cow_user_page(struct page *dst, struct page *src,
|
||||
if (!likely(pte_same(*vmf->pte, vmf->orig_pte))) {
|
||||
/* The PTE changed under us, update local tlb */
|
||||
update_mmu_tlb(vma, addr, vmf->pte);
|
||||
ret = false;
|
||||
ret = -EAGAIN;
|
||||
goto pte_unlock;
|
||||
}
|
||||
|
||||
@@ -2994,7 +3003,7 @@ warn:
|
||||
}
|
||||
}
|
||||
|
||||
ret = true;
|
||||
ret = 0;
|
||||
|
||||
pte_unlock:
|
||||
if (locked)
|
||||
@@ -3183,17 +3192,20 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
|
||||
if (!new_page)
|
||||
goto out;
|
||||
|
||||
if (!cow_user_page(new_page, old_page, vmf)) {
|
||||
ret = cow_user_page(new_page, old_page, vmf);
|
||||
if (ret) {
|
||||
/*
|
||||
* COW failed, if the fault was solved by other,
|
||||
* it's fine. If not, userspace would re-fault on
|
||||
* the same address and we will handle the fault
|
||||
* from the second attempt.
|
||||
* The -EHWPOISON case will not be retried.
|
||||
*/
|
||||
put_page(new_page);
|
||||
if (old_page)
|
||||
put_page(old_page);
|
||||
return 0;
|
||||
|
||||
return ret == -EHWPOISON ? VM_FAULT_HWPOISON : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -992,8 +992,9 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
|
||||
/* wait for complete transmission of current pdu */
|
||||
wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
|
||||
|
||||
if (sk->sk_err)
|
||||
return -sk->sk_err;
|
||||
err = sock_error(sk);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return size;
|
||||
|
||||
@@ -51,7 +51,7 @@ enum {
|
||||
static struct percpu_counter mptcp_sockets_allocated;
|
||||
|
||||
static void __mptcp_destroy_sock(struct sock *sk);
|
||||
static void __mptcp_check_send_data_fin(struct sock *sk);
|
||||
static void mptcp_check_send_data_fin(struct sock *sk);
|
||||
|
||||
DEFINE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions);
|
||||
static struct net_device mptcp_napi_dev;
|
||||
@@ -355,8 +355,7 @@ static bool mptcp_pending_data_fin_ack(struct sock *sk)
|
||||
{
|
||||
struct mptcp_sock *msk = mptcp_sk(sk);
|
||||
|
||||
return !__mptcp_check_fallback(msk) &&
|
||||
((1 << sk->sk_state) &
|
||||
return ((1 << sk->sk_state) &
|
||||
(TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK)) &&
|
||||
msk->write_seq == READ_ONCE(msk->snd_una);
|
||||
}
|
||||
@@ -509,9 +508,6 @@ static bool mptcp_check_data_fin(struct sock *sk)
|
||||
u64 rcv_data_fin_seq;
|
||||
bool ret = false;
|
||||
|
||||
if (__mptcp_check_fallback(msk))
|
||||
return ret;
|
||||
|
||||
/* Need to ack a DATA_FIN received from a peer while this side
|
||||
* of the connection is in ESTABLISHED, FIN_WAIT1, or FIN_WAIT2.
|
||||
* msk->rcv_data_fin was set when parsing the incoming options
|
||||
@@ -549,7 +545,8 @@ static bool mptcp_check_data_fin(struct sock *sk)
|
||||
}
|
||||
|
||||
ret = true;
|
||||
mptcp_send_ack(msk);
|
||||
if (!__mptcp_check_fallback(msk))
|
||||
mptcp_send_ack(msk);
|
||||
mptcp_close_wake_up(sk);
|
||||
}
|
||||
return ret;
|
||||
@@ -1612,7 +1609,7 @@ out:
|
||||
if (!mptcp_timer_pending(sk))
|
||||
mptcp_reset_timer(sk);
|
||||
if (copied)
|
||||
__mptcp_check_send_data_fin(sk);
|
||||
mptcp_check_send_data_fin(sk);
|
||||
}
|
||||
|
||||
static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk)
|
||||
@@ -2451,7 +2448,6 @@ static void mptcp_worker(struct work_struct *work)
|
||||
if (unlikely((1 << state) & (TCPF_CLOSE | TCPF_LISTEN)))
|
||||
goto unlock;
|
||||
|
||||
mptcp_check_data_fin_ack(sk);
|
||||
mptcp_flush_join_list(msk);
|
||||
|
||||
mptcp_check_fastclose(msk);
|
||||
@@ -2462,7 +2458,8 @@ static void mptcp_worker(struct work_struct *work)
|
||||
if (test_and_clear_bit(MPTCP_WORK_EOF, &msk->flags))
|
||||
mptcp_check_for_eof(msk);
|
||||
|
||||
__mptcp_check_send_data_fin(sk);
|
||||
mptcp_check_send_data_fin(sk);
|
||||
mptcp_check_data_fin_ack(sk);
|
||||
mptcp_check_data_fin(sk);
|
||||
|
||||
/* There is no point in keeping around an orphaned sk timedout or
|
||||
@@ -2591,6 +2588,12 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how)
|
||||
pr_debug("Fallback");
|
||||
ssk->sk_shutdown |= how;
|
||||
tcp_shutdown(ssk, how);
|
||||
|
||||
/* simulate the data_fin ack reception to let the state
|
||||
* machine move forward
|
||||
*/
|
||||
WRITE_ONCE(mptcp_sk(sk)->snd_una, mptcp_sk(sk)->snd_nxt);
|
||||
mptcp_schedule_work(sk);
|
||||
} else {
|
||||
pr_debug("Sending DATA_FIN on subflow %p", ssk);
|
||||
tcp_send_ack(ssk);
|
||||
@@ -2630,7 +2633,7 @@ static int mptcp_close_state(struct sock *sk)
|
||||
return next & TCP_ACTION_FIN;
|
||||
}
|
||||
|
||||
static void __mptcp_check_send_data_fin(struct sock *sk)
|
||||
static void mptcp_check_send_data_fin(struct sock *sk)
|
||||
{
|
||||
struct mptcp_subflow_context *subflow;
|
||||
struct mptcp_sock *msk = mptcp_sk(sk);
|
||||
@@ -2648,18 +2651,6 @@ static void __mptcp_check_send_data_fin(struct sock *sk)
|
||||
|
||||
WRITE_ONCE(msk->snd_nxt, msk->write_seq);
|
||||
|
||||
/* fallback socket will not get data_fin/ack, can move to the next
|
||||
* state now
|
||||
*/
|
||||
if (__mptcp_check_fallback(msk)) {
|
||||
if ((1 << sk->sk_state) & (TCPF_CLOSING | TCPF_LAST_ACK)) {
|
||||
inet_sk_state_store(sk, TCP_CLOSE);
|
||||
mptcp_close_wake_up(sk);
|
||||
} else if (sk->sk_state == TCP_FIN_WAIT1) {
|
||||
inet_sk_state_store(sk, TCP_FIN_WAIT2);
|
||||
}
|
||||
}
|
||||
|
||||
mptcp_flush_join_list(msk);
|
||||
mptcp_for_each_subflow(msk, subflow) {
|
||||
struct sock *tcp_sk = mptcp_subflow_tcp_sock(subflow);
|
||||
@@ -2680,7 +2671,7 @@ static void __mptcp_wr_shutdown(struct sock *sk)
|
||||
WRITE_ONCE(msk->write_seq, msk->write_seq + 1);
|
||||
WRITE_ONCE(msk->snd_data_fin_enable, 1);
|
||||
|
||||
__mptcp_check_send_data_fin(sk);
|
||||
mptcp_check_send_data_fin(sk);
|
||||
}
|
||||
|
||||
static void __mptcp_destroy_sock(struct sock *sk)
|
||||
@@ -2807,6 +2798,12 @@ static int mptcp_disconnect(struct sock *sk, int flags)
|
||||
struct mptcp_subflow_context *subflow;
|
||||
struct mptcp_sock *msk = mptcp_sk(sk);
|
||||
|
||||
/* Deny disconnect if other threads are blocked in sk_wait_event()
|
||||
* or inet_wait_for_connect().
|
||||
*/
|
||||
if (sk->sk_wait_pending)
|
||||
return -EBUSY;
|
||||
|
||||
mptcp_do_flush_join_list(msk);
|
||||
|
||||
mptcp_for_each_subflow(msk, subflow) {
|
||||
@@ -2845,6 +2842,7 @@ struct sock *mptcp_sk_clone(const struct sock *sk,
|
||||
inet_sk(nsk)->pinet6 = mptcp_inet6_sk(nsk);
|
||||
#endif
|
||||
|
||||
nsk->sk_wait_pending = 0;
|
||||
__mptcp_init_sock(nsk);
|
||||
|
||||
msk = mptcp_sk(nsk);
|
||||
|
||||
@@ -1653,14 +1653,16 @@ static void subflow_state_change(struct sock *sk)
|
||||
{
|
||||
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
|
||||
struct sock *parent = subflow->conn;
|
||||
struct mptcp_sock *msk;
|
||||
|
||||
__subflow_state_change(sk);
|
||||
|
||||
msk = mptcp_sk(parent);
|
||||
if (subflow_simultaneous_connect(sk)) {
|
||||
mptcp_propagate_sndbuf(parent, sk);
|
||||
mptcp_do_fallback(sk);
|
||||
mptcp_rcv_space_init(mptcp_sk(parent), sk);
|
||||
pr_fallback(mptcp_sk(parent));
|
||||
mptcp_rcv_space_init(msk, sk);
|
||||
pr_fallback(msk);
|
||||
subflow->conn_finished = 1;
|
||||
mptcp_set_connected(parent);
|
||||
}
|
||||
@@ -1676,11 +1678,12 @@ static void subflow_state_change(struct sock *sk)
|
||||
|
||||
subflow_sched_work_if_closed(mptcp_sk(parent), sk);
|
||||
|
||||
if (__mptcp_check_fallback(mptcp_sk(parent)) &&
|
||||
!subflow->rx_eof && subflow_is_done(sk)) {
|
||||
subflow->rx_eof = 1;
|
||||
mptcp_subflow_eof(parent);
|
||||
}
|
||||
/* when the fallback subflow closes the rx side, trigger a 'dummy'
|
||||
* ingress data fin, so that the msk state will follow along
|
||||
*/
|
||||
if (__mptcp_check_fallback(msk) && subflow_is_done(sk) && msk->first == sk &&
|
||||
mptcp_update_rcv_data_fin(msk, READ_ONCE(msk->ack_seq), true))
|
||||
mptcp_schedule_work(parent);
|
||||
}
|
||||
|
||||
static int subflow_ulp_init(struct sock *sk)
|
||||
|
||||
@@ -32,6 +32,13 @@ else
|
||||
ignore="$ignore ( -path ${tree}tools ) -prune -o"
|
||||
fi
|
||||
|
||||
# gtags(1) refuses to index any file outside of its current working dir.
|
||||
# If gtags indexing is requested and the build output directory is not
|
||||
# the kernel source tree, index all files in absolute-path form.
|
||||
if [[ "$1" == "gtags" && -n "${tree}" ]]; then
|
||||
tree=$(realpath "$tree")/
|
||||
fi
|
||||
|
||||
# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
|
||||
if [ "${ALLSOURCE_ARCHS}" = "" ]; then
|
||||
ALLSOURCE_ARCHS=${SRCARCH}
|
||||
@@ -131,7 +138,7 @@ docscope()
|
||||
|
||||
dogtags()
|
||||
{
|
||||
all_target_sources | gtags -i -f -
|
||||
all_target_sources | gtags -i -C "${tree:-.}" -f - "$PWD"
|
||||
}
|
||||
|
||||
# Basic regular expressions with an optional /kind-spec/ for ctags and
|
||||
|
||||
@@ -1357,10 +1357,23 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
|
||||
|
||||
/* Find the kernel map using the '_stext' symbol */
|
||||
if (!kallsyms__get_function_start(kallsyms_filename, "_stext", &stext)) {
|
||||
u64 replacement_size = 0;
|
||||
|
||||
list_for_each_entry(new_map, &md.maps, node) {
|
||||
if (stext >= new_map->start && stext < new_map->end) {
|
||||
u64 new_size = new_map->end - new_map->start;
|
||||
|
||||
if (!(stext >= new_map->start && stext < new_map->end))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* On some architectures, ARM64 for example, the kernel
|
||||
* text can get allocated inside of the vmalloc segment.
|
||||
* Select the smallest matching segment, in case stext
|
||||
* falls within more than one in the list.
|
||||
*/
|
||||
if (!replacement_map || new_size < replacement_size) {
|
||||
replacement_map = new_map;
|
||||
break;
|
||||
replacement_size = new_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user