* We want the lowest bit of offset available for in-use/free
         * indicator, so force >= 16bit alignment and make size even.
         */
-       if (unlikely(align < 2))
-               align = 2;
+       if (unlikely(align < PCPU_MIN_ALLOC_SIZE))
+               align = PCPU_MIN_ALLOC_SIZE;
 
-       size = ALIGN(size, 2);
+       size = ALIGN(size, PCPU_MIN_ALLOC_SIZE);
 
        if (unlikely(!size || size > PCPU_MIN_UNIT_SIZE || align > PAGE_SIZE ||
                     !is_power_of_2(align))) {
        static int smap[PERCPU_DYNAMIC_EARLY_SLOTS] __initdata;
        static int dmap[PERCPU_DYNAMIC_EARLY_SLOTS] __initdata;
        size_t size_sum = ai->static_size + ai->reserved_size + ai->dyn_size;
+       size_t static_size, dyn_size;
        struct pcpu_chunk *chunk;
        unsigned long *group_offsets;
        size_t *group_sizes;
        PCPU_SETUP_BUG_ON(ai->unit_size < PCPU_MIN_UNIT_SIZE);
        PCPU_SETUP_BUG_ON(ai->dyn_size < PERCPU_DYNAMIC_EARLY_SIZE);
        PCPU_SETUP_BUG_ON(!ai->dyn_size);
+       PCPU_SETUP_BUG_ON(!IS_ALIGNED(ai->reserved_size, PCPU_MIN_ALLOC_SIZE));
        PCPU_SETUP_BUG_ON(pcpu_verify_alloc_info(ai) < 0);
 
        /* process group information and build config tables accordingly */
        for (i = 0; i < pcpu_nr_slots; i++)
                INIT_LIST_HEAD(&pcpu_slot[i]);
 
+       /*
+        * The end of the static region needs to be aligned with the
+        * minimum allocation size as this offsets the reserved and
+        * dynamic region.  The first chunk ends page aligned by
+        * expanding the dynamic region, therefore the dynamic region
+        * can be shrunk to compensate while still staying above the
+        * configured sizes.
+        */
+       static_size = ALIGN(ai->static_size, PCPU_MIN_ALLOC_SIZE);
+       dyn_size = ai->dyn_size - (static_size - ai->static_size);
+
        /*
         * Initialize first chunk.
         * If the reserved_size is non-zero, this initializes the reserved
         * pcpu_first_chunk, will always point to the chunk that serves
         * the dynamic region.
         */
-       tmp_addr = (unsigned long)base_addr + ai->static_size;
-       map_size = ai->reserved_size ?: ai->dyn_size;
+       tmp_addr = (unsigned long)base_addr + static_size;
+       map_size = ai->reserved_size ?: dyn_size;
        chunk = pcpu_alloc_first_chunk(tmp_addr, map_size, smap,
                                       ARRAY_SIZE(smap));
 
        if (ai->reserved_size) {
                pcpu_reserved_chunk = chunk;
 
-               tmp_addr = (unsigned long)base_addr + ai->static_size +
+               tmp_addr = (unsigned long)base_addr + static_size +
                           ai->reserved_size;
-               map_size = ai->dyn_size;
+               map_size = dyn_size;
                chunk = pcpu_alloc_first_chunk(tmp_addr, map_size, dmap,
                                               ARRAY_SIZE(dmap));
        }