set related/upsell products programatically only works for 1 product

This part caused your issue, if you created this object outsize the foreach loop, that means it is a "global" object. So, we need to create a new object inside the loop.

$linkData = $productLinks //Magento\Catalog\Api\Data\ProductLinkInterface

It should like this:

 /** @var \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinks **/
$linkData = $productLinks->create();

See more here Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper::setProductLinks

Set related products programatically Magento 2