Copy and pasted the contents of the function into the interrupt and the time-sink went away
We can't see what your code is, what the optimization settings are being used etc., but its not that hard to believe that when 'calling' the function its doing a lot more- the function has no idea 'who' may be calling it and has to do 'everything' because it does not know what parameters are passed (if any). Taking the same function and 'inlining' it (manually, or better just use the inline attribute for the function, whatever that may be for your compiler) , now the compiler can optimize it because it knows what the parameters are and can eliminate everything that's not relevant. 12 lines sounds like very little, but who knows (we don't) what is hiding (defines/macros/other function calls) in those 12 lines. Its also not hard to believe 12 lines can expand into a truckload of code behind the scenes.
The function call may take long, but its not the call that takes the time, its the function not knowing ahead of time who is calling it and what is has passed to it.
Not sure what compiler is being used, but there will be a way to keep 'intermediate' files (like .i , .s), generate a combined c/asm listing (.lst), etc. - then you can see exactly whats going on by reading these files (.lst file is handy). I'm not great at this stuff, but after a while of checking what the compiler is up to, you get a pretty good idea whats going on under the hood.