Skip to content
3 changes: 1 addition & 2 deletions drivers/edac/i10nm_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,10 @@ static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus,
if (unlikely(pci_enable_device(pdev) < 0)) {
edac_dbg(2, "Failed to enable device %02x:%02x.%x\n",
bus, dev, fun);
pci_dev_put(pdev);
return NULL;
}

pci_dev_get(pdev);

return pdev;
}

Expand Down
9 changes: 6 additions & 3 deletions drivers/scsi/ses.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,9 +607,11 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
/* these elements are optional */
type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) {
addl_desc_ptr += addl_desc_ptr[1] + 2;

if (addl_desc_ptr + 1 >= ses_dev->page10 + ses_dev->page10_len)
addl_desc_ptr = NULL;
}
}
}
kfree(buf);
Expand Down Expand Up @@ -831,7 +833,8 @@ static void ses_intf_remove_enclosure(struct scsi_device *sdev)
kfree(ses_dev->page2);
kfree(ses_dev);

kfree(edev->component[0].scratch);
if (edev->components)
kfree(edev->component[0].scratch);

put_device(&edev->edev);
enclosure_unregister(edev);
Expand Down
3 changes: 2 additions & 1 deletion kernel/cgroup/cpuset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1346,7 +1346,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cs, int cmd,
* A parent can be left with no CPU as long as there is no
* task directly associated with the parent partition.
*/
if (!cpumask_intersects(cs->cpus_allowed, parent->effective_cpus) &&
if (cpumask_subset(parent->effective_cpus, cs->cpus_allowed) &&
partition_is_populated(parent, cs))
return PERR_NOCPUS;

Expand Down Expand Up @@ -2324,6 +2324,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
new_prs = -new_prs;
spin_lock_irq(&callback_lock);
cs->partition_root_state = new_prs;
WRITE_ONCE(cs->prs_err, err);
spin_unlock_irq(&callback_lock);
/*
* Update child cpusets, if present.
Expand Down
2 changes: 1 addition & 1 deletion net/bluetooth/hci_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1815,7 +1815,7 @@ static int hci_create_cis_sync(struct hci_dev *hdev, void *data)
continue;

/* Check if all CIS(s) belonging to a CIG are ready */
if (conn->link->state != BT_CONNECTED ||
if (!conn->link || conn->link->state != BT_CONNECTED ||
conn->state != BT_CONNECT) {
cmd.cp.num_cis = 0;
break;
Expand Down
8 changes: 8 additions & 0 deletions net/core/skmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,13 @@ static void sk_psock_backlog(struct work_struct *work)
u32 len, off;
int ret;

/* Increment the psock refcnt to synchronize with close(fd) path in
* sock_map_close(), ensuring we wait for backlog thread completion
* before sk_socket freed. If refcnt increment fails, it indicates
* sock_map_close() completed with sk_socket potentially already freed.
*/
if (!sk_psock_get(psock->sk))
return;
mutex_lock(&psock->work_mutex);
if (unlikely(state->skb)) {
spin_lock_bh(&psock->ingress_lock);
Expand Down Expand Up @@ -697,6 +704,7 @@ static void sk_psock_backlog(struct work_struct *work)
}
end:
mutex_unlock(&psock->work_mutex);
sk_psock_put(psock->sk, psock);
}

struct sk_psock *sk_psock_init(struct sock *sk, int node)
Expand Down
69 changes: 40 additions & 29 deletions net/core/sock_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -1569,15 +1569,16 @@ void sock_map_unhash(struct sock *sk)
psock = sk_psock(sk);
if (unlikely(!psock)) {
rcu_read_unlock();
if (sk->sk_prot->unhash)
sk->sk_prot->unhash(sk);
return;
saved_unhash = READ_ONCE(sk->sk_prot)->unhash;
} else {
saved_unhash = psock->saved_unhash;
sock_map_remove_links(sk, psock);
rcu_read_unlock();
}

saved_unhash = psock->saved_unhash;
sock_map_remove_links(sk, psock);
rcu_read_unlock();
saved_unhash(sk);
if (WARN_ON_ONCE(saved_unhash == sock_map_unhash))
return;
if (saved_unhash)
saved_unhash(sk);
}
EXPORT_SYMBOL_GPL(sock_map_unhash);

Expand All @@ -1590,17 +1591,18 @@ void sock_map_destroy(struct sock *sk)
psock = sk_psock_get(sk);
if (unlikely(!psock)) {
rcu_read_unlock();
if (sk->sk_prot->destroy)
sk->sk_prot->destroy(sk);
return;
saved_destroy = READ_ONCE(sk->sk_prot)->destroy;
} else {
saved_destroy = psock->saved_destroy;
sock_map_remove_links(sk, psock);
rcu_read_unlock();
sk_psock_stop(psock);
sk_psock_put(sk, psock);
}

saved_destroy = psock->saved_destroy;
sock_map_remove_links(sk, psock);
rcu_read_unlock();
sk_psock_stop(psock);
sk_psock_put(sk, psock);
saved_destroy(sk);
if (WARN_ON_ONCE(saved_destroy == sock_map_destroy))
return;
if (saved_destroy)
saved_destroy(sk);
}
EXPORT_SYMBOL_GPL(sock_map_destroy);

Expand All @@ -1611,20 +1613,29 @@ void sock_map_close(struct sock *sk, long timeout)

lock_sock(sk);
rcu_read_lock();
psock = sk_psock_get(sk);
if (unlikely(!psock)) {
psock = sk_psock(sk);
if (likely(psock)) {
saved_close = psock->saved_close;
sock_map_remove_links(sk, psock);
psock = sk_psock_get(sk);
if (unlikely(!psock))
goto no_psock;
rcu_read_unlock();
sk_psock_stop(psock);
release_sock(sk);
cancel_work_sync(&psock->work);
sk_psock_put(sk, psock);
} else {
saved_close = READ_ONCE(sk->sk_prot)->close;
no_psock:
rcu_read_unlock();
release_sock(sk);
return sk->sk_prot->close(sk, timeout);
}

saved_close = psock->saved_close;
sock_map_remove_links(sk, psock);
rcu_read_unlock();
sk_psock_stop(psock);
release_sock(sk);
cancel_work_sync(&psock->work);
sk_psock_put(sk, psock);
/* Make sure we do not recurse. This is a bug.
* Leak the socket instead of crashing on a stack overflow.
*/
if (WARN_ON_ONCE(saved_close == sock_map_close))
return;
saved_close(sk, timeout);
}
EXPORT_SYMBOL_GPL(sock_map_close);
Expand Down
6 changes: 5 additions & 1 deletion net/netlink/genetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1182,13 +1182,17 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb)
op.policy,
op.maxattr);
if (err)
return err;
goto err_free_state;
}
}

if (!ctx->state)
return -ENODATA;
return 0;

err_free_state:
netlink_policy_dump_free(ctx->state);
return err;
}

static void *ctrl_dumppolicy_prep(struct sk_buff *skb,
Expand Down
14 changes: 12 additions & 2 deletions net/netlink/policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ int netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate,

err = add_policy(&state, policy, maxtype);
if (err)
return err;
goto err_try_undo;

for (policy_idx = 0;
policy_idx < state->n_alloc && state->policies[policy_idx].policy;
Expand All @@ -164,7 +164,7 @@ int netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate,
policy[type].nested_policy,
policy[type].len);
if (err)
return err;
goto err_try_undo;
break;
default:
break;
Expand All @@ -174,6 +174,16 @@ int netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate,

*pstate = state;
return 0;

err_try_undo:
/* Try to preserve reasonable unwind semantics - if we're starting from
* scratch clean up fully, otherwise record what we got and caller will.
*/
if (!*pstate)
netlink_policy_dump_free(state);
else
*pstate = state;
return err;
}

static bool
Expand Down
2 changes: 1 addition & 1 deletion tools/objtool/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
return false;

insn = find_insn(file, func->sec, func->offset);
if (!insn->func)
if (!insn || !insn->func)
return false;

func_for_each_insn(file, func, insn) {
Expand Down
1 change: 1 addition & 0 deletions tools/testing/selftests/cgroup/test_cpuset_prs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ TEST_MATRIX=(
# Taking away all CPUs from parent or itself if there are tasks
# will make the partition invalid.
" S+ C2-3:P1:S+ C3:P1 . . T C2-3 . . 0 A1:2-3,A2:2-3 A1:P1,A2:P-1"
" S+ C3:P1:S+ C3 . . T P1 . . 0 A1:3,A2:3 A1:P1,A2:P-1"
" S+ $SETUP_A123_PARTITIONS . T:C2-3 . . . 0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1"
" S+ $SETUP_A123_PARTITIONS . T:C2-3:C1-3 . . . 0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"

Expand Down
Loading