u8                      retrans_times;
 };
 
-/* max value of mptcp_addr_info.id */
-#define MAX_ADDR_ID            U8_MAX
-#define BITMAP_SZ DIV_ROUND_UP(MAX_ADDR_ID + 1, BITS_PER_LONG)
-
 struct pm_nl_pernet {
        /* protects pernet updates */
        spinlock_t              lock;
        unsigned int            local_addr_max;
        unsigned int            subflows_max;
        unsigned int            next_id;
-       unsigned long           id_bitmap[BITMAP_SZ];
+       DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
 };
 
 #define MPTCP_PM_ADDR_MAX      8
 #define ADD_ADDR_RETRANS_MAX   3
 
 static bool addresses_equal(const struct mptcp_addr_info *a,
-                           struct mptcp_addr_info *b, bool use_port)
+                           const struct mptcp_addr_info *b, bool use_port)
 {
        bool addr_equals = false;
 
                if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW))
                        continue;
 
+               if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
+                       continue;
+
                if (entry->addr.family != sk->sk_family) {
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
                        if ((entry->addr.family == AF_INET &&
                                continue;
                }
 
-               /* avoid any address already in use by subflows and
-                * pending join
-                */
-               if (!lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) {
-                       ret = entry;
-                       break;
-               }
+               ret = entry;
+               break;
        }
        rcu_read_unlock();
        return ret;
 }
 
 static struct mptcp_pm_addr_entry *
-select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos)
+select_signal_address(struct pm_nl_pernet *pernet, struct mptcp_sock *msk)
 {
        struct mptcp_pm_addr_entry *entry, *ret = NULL;
-       int i = 0;
 
        rcu_read_lock();
        /* do not keep any additional per socket state, just signal
         * can lead to additional addresses not being announced.
         */
        list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
+               if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
+                       continue;
+
                if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
                        continue;
-               if (i++ == pos) {
-                       ret = entry;
-                       break;
-               }
+
+               ret = entry;
+               break;
        }
        rcu_read_unlock();
        return ret;
 
 static void check_work_pending(struct mptcp_sock *msk)
 {
-       if (msk->pm.add_addr_signaled == mptcp_pm_get_add_addr_signal_max(msk) &&
-           (msk->pm.local_addr_used == mptcp_pm_get_local_addr_max(msk) ||
-            msk->pm.subflows == mptcp_pm_get_subflows_max(msk)))
+       struct pm_nl_pernet *pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
+
+       if (msk->pm.subflows == mptcp_pm_get_subflows_max(msk) ||
+           (find_next_and_bit(pernet->id_bitmap, msk->pm.id_avail_bitmap,
+                              MPTCP_PM_MAX_ADDR_ID + 1, 0) == MPTCP_PM_MAX_ADDR_ID + 1))
                WRITE_ONCE(msk->pm.work_pending, false);
 }
 
        return i;
 }
 
+static struct mptcp_pm_addr_entry *
+__lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
+{
+       struct mptcp_pm_addr_entry *entry;
+
+       list_for_each_entry(entry, &pernet->local_addr_list, list) {
+               if (entry->addr.id == id)
+                       return entry;
+       }
+       return NULL;
+}
+
+static int
+lookup_id_by_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *addr)
+{
+       struct mptcp_pm_addr_entry *entry;
+       int ret = -1;
+
+       rcu_read_lock();
+       list_for_each_entry(entry, &pernet->local_addr_list, list) {
+               if (addresses_equal(&entry->addr, addr, entry->addr.port)) {
+                       ret = entry->addr.id;
+                       break;
+               }
+       }
+       rcu_read_unlock();
+       return ret;
+}
+
 static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
 {
        struct sock *sk = (struct sock *)msk;
        local_addr_max = mptcp_pm_get_local_addr_max(msk);
        subflows_max = mptcp_pm_get_subflows_max(msk);
 
+       /* do lazy endpoint usage accounting for the MPC subflows */
+       if (unlikely(!(msk->pm.status & BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED))) && msk->first) {
+               struct mptcp_addr_info local;
+               int mpc_id;
+
+               local_address((struct sock_common *)msk->first, &local);
+               mpc_id = lookup_id_by_addr(pernet, &local);
+               if (mpc_id < 0)
+                       __clear_bit(mpc_id, msk->pm.id_avail_bitmap);
+
+               msk->pm.status |= BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED);
+       }
+
        pr_debug("local %d:%d signal %d:%d subflows %d:%d\n",
                 msk->pm.local_addr_used, local_addr_max,
                 msk->pm.add_addr_signaled, add_addr_signal_max,
 
        /* check first for announce */
        if (msk->pm.add_addr_signaled < add_addr_signal_max) {
-               local = select_signal_address(pernet,
-                                             msk->pm.add_addr_signaled);
+               local = select_signal_address(pernet, msk);
 
                if (local) {
                        if (mptcp_pm_alloc_anno_list(msk, local)) {
+                               __clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
                                msk->pm.add_addr_signaled++;
                                mptcp_pm_announce_addr(msk, &local->addr, false);
                                mptcp_pm_nl_addr_send_ack(msk);
                        }
-               } else {
-                       /* pick failed, avoid fourther attempts later */
-                       msk->pm.local_addr_used = add_addr_signal_max;
                }
-
-               check_work_pending(msk);
        }
 
        /* check if should create a new subflow */
                        int i, nr;
 
                        msk->pm.local_addr_used++;
-                       check_work_pending(msk);
                        nr = fill_remote_addresses_vec(msk, fullmesh, addrs);
+                       if (nr)
+                               __clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
                        spin_unlock_bh(&msk->pm.lock);
                        for (i = 0; i < nr; i++)
                                __mptcp_subflow_connect(sk, &local->addr, &addrs[i]);
                        spin_lock_bh(&msk->pm.lock);
-                       return;
                }
-
-               /* lookup failed, avoid fourther attempts later */
-               msk->pm.local_addr_used = local_addr_max;
-               check_work_pending(msk);
        }
+       check_work_pending(msk);
 }
 
 static void mptcp_pm_nl_fully_established(struct mptcp_sock *msk)
                        msk->pm.subflows--;
                        __MPTCP_INC_STATS(sock_net(sk), rm_type);
                }
+               __set_bit(rm_list->ids[1], msk->pm.id_avail_bitmap);
                if (!removed)
                        continue;
 
 
        msk_owned_by_me(msk);
 
+       if (!(pm->status & MPTCP_PM_WORK_MASK))
+               return;
+
        spin_lock_bh(&msk->pm.lock);
 
        pr_debug("msk=%p status=%x", msk, pm->status);
        /* to keep the code simple, don't do IDR-like allocation for address ID,
         * just bail when we exceed limits
         */
-       if (pernet->next_id == MAX_ADDR_ID)
+       if (pernet->next_id == MPTCP_PM_MAX_ADDR_ID)
                pernet->next_id = 1;
        if (pernet->addrs >= MPTCP_PM_ADDR_MAX)
                goto out;
        if (!entry->addr.id) {
 find_next:
                entry->addr.id = find_next_zero_bit(pernet->id_bitmap,
-                                                   MAX_ADDR_ID + 1,
+                                                   MPTCP_PM_MAX_ADDR_ID + 1,
                                                    pernet->next_id);
                if (!entry->addr.id && pernet->next_id != 1) {
                        pernet->next_id = 1;
        return 0;
 }
 
-static struct mptcp_pm_addr_entry *
-__lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
-{
-       struct mptcp_pm_addr_entry *entry;
-
-       list_for_each_entry(entry, &pernet->local_addr_list, list) {
-               if (entry->addr.id == id)
-                       return entry;
-       }
-       return NULL;
-}
-
 int mptcp_pm_get_flags_and_ifindex_by_id(struct net *net, unsigned int id,
                                         u8 *flags, int *ifindex)
 {
        list_splice_init(&pernet->local_addr_list, &free_list);
        __reset_counters(pernet);
        pernet->next_id = 1;
-       bitmap_zero(pernet->id_bitmap, MAX_ADDR_ID + 1);
+       bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
        spin_unlock_bh(&pernet->lock);
        mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list);
        synchronize_rcu();
        pernet = net_generic(net, pm_nl_pernet_id);
 
        spin_lock_bh(&pernet->lock);
-       for (i = id; i < MAX_ADDR_ID + 1; i++) {
+       for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
                if (test_bit(i, pernet->id_bitmap)) {
                        entry = __lookup_addr_by_id(pernet, i);
                        if (!entry)