The bottom halves are implemented as tasklets (deferred interrupt context), workqueues (process context) and softirqs (rarely, only 9 of those in Linux kernel).
The timer interrupt handler checks which of the 9 softirqs are to be executed (scheduler, hrtimers, network rx/tx, tasklets, etc.). If there is any pending softirq, (say a list of tasklets that the top-half has notified) then those get executed. As for any tasklet, this is true for any other softirq too. Also, because tasklet is a kind of softirq it can only be executed on the same CPU core.
On the contrary, the workqueues are executed when the corresponding process subsequently context switches in. Hence, unlike tasklets, these can sleep and can be scheduled on other CPU cores too.