The JSR is a big scan time hit, as well as the return, JMP and LBL are too. Especially when parameters are passed. And indirect addressing always increases scan time.
I don't recall the numbers but a JSR takes something like 15 times what an OTE instruction takes in a PLC-5 in CPU time.
I have used "common driver code" when there are dozens of iterations though.
I don't put the JSRs inside the loop though, rather loop a pointer through an array of UDTs...yes, you can make a UDT in RSLogix5, you just gotta do it by hand. I never put real I/O inside the loop. Map the Inputs and Outputs externally so you can see them in a static fashion, and perform re-assignment for quicker maintenance if necessary.
Once you get the algorithm and is options nailed down, there is nothing wrong with looping through them and using indirect addressing, and then copying one of them to your HMI faceplate data area.
If there are less than a dozen or so, or if they might need to have unique functions later, and you don't mind editing each instance individually to make changes, then just use the brute force method. It will always run faster, and you can put a page title at the beginning of each motor control section.
Then for ease of navigation in RSLogix 5, you can take advantage of Advanced Diagnostics (CTRL+D) to make finding the code very easy.
I have not used parameter passing with a PLC-5 except for conditional JSRs for special math or data manipulation.
Yes, getting carried away jumping back and forth 100 times to 10 and twenty rung SUBs is a waste of horsepower.
On the other side of the debate, If you have scan time to spare for indirection, using common driver code can make handling lots of equipment (think 100 pumps with the same feedback switches) easier on the programmer, and free up instruction space for data collection. In a PLC5, though, would do it with JMP and LBL, with a pointer control like a FOR NEXT loop.